@ServerEndpoint 주석: 2023 최신 공유, springboot의 경량 웹소켓

@서버엔드포인트:

주로 현재 클래스를 websocket 서버로 정의하고 주석 값은 사용자 연결의 터미널 액세스 URL 주소를 모니터링하는 데 사용되며 클라이언트는 이 URL을 통해 WebSocket 서버에 연결할 수 있습니다.

설명: 이 프로젝트는 springboot 통합 websocket입니다.
내 프로젝트는 gradel을 사용하여 종속성을 가져옵니다. maven 종속성은 아래에 첨부됩니다. 버전은 springboot와 일치합니다.

build.gradle
    compile group:  'org.springframework.boot', name: 'spring-boot-starter-websocket', version: '2.0.4.RELEASE'

pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

이 문서는 주석 프로그래밍을 채택하고 다음과 같이 빠른 개발이 이루어집니다.
코어 프로세서 MyWebSocketServer.java


@ServerEndpoint(value = "/mysocket", encoders = AnswerEncoder.class)
@Component
@Slf4j
public class MyWebSocketServer {
    
    

    /**
     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
     */
    private static int onlineCount = 0;

    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
     */
    private static final CopyOnWriteArraySet<ScreenWebSocketServer> WEB_SOCKET_SET = new CopyOnWriteArraySet<ScreenWebSocketServer>();

    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据。
     */
    private Session session;

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
    
    
        this.session = session;
        // 将当前连接加入到set中
        WEB_SOCKET_SET.add(this);
        // 连接数+1
        addOnlineCount();
        log.info("MyWebSocketServer 加入新的连接,当前连接数为" + getOnlineCount());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
    
    
        // 将当前连接从set中移除
        WEB_SOCKET_SET.remove(this);
        // 连接数-1
        subOnlineCount();
        log.info("MyWebSocketServer 有一连接关闭!当前连接数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
    
    
        log.info("MyWebSocketServer 收到来自窗口" + session.getId() + "的信息:" + message);
    }

    /**
     * @param session 连接session
     * @param error   措施信息
     */
    @OnError
    public void onError(Session session, Throwable error) {
    
    
        log.error("MyWebSocketServer 连接发生错误");
        error.printStackTrace();
    }


    /**
     * <p>@Description:給session连接推送消息</p>
     * <p>@param [message]</p>
     * <p>@return void</p>
     * <p>@throws </p>
     */
    private void sendMessage(Object message) throws IOException {
    
    
        try {
    
    
            this.session.getBasicRemote().sendObject(message);
        } catch (EncodeException e) {
    
    
            e.printStackTrace();
            log.error("MyWebSocketServer 向客户端推送数据发生错误");
        }
    }

    /**
     * <p>@Description:向所有连接群发消息</p>
     * <p>@param [message]</p>
     * <p>@return void</p>
     * <p>@throws </p>
     */
    public static void sendMessageToAll(Object message){
    
    
        for (ScreenWebSocketServer item : WEB_SOCKET_SET) {
    
    
            try {
    
    
                item.sendMessage(message);
            } catch (IOException e) {
    
    
                log.error("MyWebSocketServer 向客户端推送数据发生错误");
            }
        }
    }

    public static synchronized int getOnlineCount() {
    
    
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
    
    
        ScreenWebSocketServer.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
    
    
        ScreenWebSocketServer.onlineCount--;
    }

    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) {
    
    
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
    
    
            return false;
        }
        ScreenWebSocketServer that = (ScreenWebSocketServer) o;
        return Objects.equals(session, that.session);
    }

    @Override
    public int hashCode() {
    
    
        return Objects.hash(session);
    }
}

AnswerEncoder.java 메시지를 보내는 인코더

public class AnswerEncoder implements Encoder.Text<Answer> {
    
    
    @Override
    public void destroy() {
    
    
        // TODO Auto-generated method stub
    }

    @Override
    public void init(EndpointConfig arg0) {
    
    
        // TODO Auto-generated method stub
    }

    @Override
    public String encode(Answer answer) throws EncodeException {
    
    
        return JSONUtil.toJsonStr(answer);
    }
}

가장 중요한 단계: ServerEndpointExporter를 스프링 컨테이너 관리에 노출하면 @ServerEndpoint 주석으로 표시된 웹소켓 프로세서를 주입하는 데 도움이 됩니다. 그렇지 않으면 위의 구성이 적용되지 않습니다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * File Name: WebsocketConfiguration
 * Description: Websocket 相关配置类
 */
@Configuration
public class WebSocketConfiguration {
    
    

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
    
    
        return new ServerEndpointExporter();
    }

}

지금까지 websocket이 구성되었으므로 호출하는 방법과 서버에서 클라이언트로 메시지를 능동적으로 푸시하는 방법은 무엇입니까? 다음 샘플 코드를 참조하십시오.


@RequestMapping("socketPushTest")
@RestController
public class MyWebSocketPushTest {
    
    

    @ApiOperation("给已连接的所有session进行群发")
    @PostMapping("/sendMessageToAll")
    public void push(@RequestBody Object data) {
    
    
        // 给前端群发数据变更消息
        Answer success = Answer.success("群发的消息-----啦啦啦");
        MyWebSocketServer.sendMessageToAll(success);
    }
}

핵심 코드는 MyWebSocketServer.sendMessageToAll(success)입니다.
이제 스프링부트 내장 웹소켓이 구성되었으며 URL을 통해 이 서비스에 연결할 수 있습니다.

아래에 내 테스트 사진을 게시하겠습니다.
설명: 내 springboot 프로젝트 시작 포트(즉, yml 파일의 server.port)는 9090
ws://127.0.0.1:9090/mysocket 입니다
. 1단계. ws 요청 사용자 시뮬레이션 1
여기에 이미지 설명 삽입
ws 요청 사용자 시뮬레이션 2
여기에 이미지 설명 삽입
idea 콘솔 인쇄 로그 확인
여기에 이미지 설명 삽입
이 시점에서 ws 연결이 성공적으로 생성되고 ws 푸시 인터페이스를 호출하여 그룹 전송을 실현한 다음 사용자 1과 사용자 2가 수신할 수 있는지 확인합니다.
여기에 이미지 설명 삽입
여기에 이미지 설명 삽입

질문과 답변: 구성 후 springboot 프로젝트에서 오류를 보고하기 시작합니다. 이 블로그의 사용 범위는 springboot+tomcat입니다. 시작 시 오류가 보고되면
maven 또는 gradle 종속성일 때
spring-boot-starter-tomcat을 제외하십시오. 구성은 다음과 같습니다 .

build.gradle
compile("org.springframework.boot:spring-boot-starter-web:2.1.4.RELEASE") {
    
    
        exclude module: "spring-boot-starter-tomcat"
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
pom.xml
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-websocket</artifactId>
		<exclusions>
			<exclusion>
				<groupId>org.springframework.boot</groupId>
				<artifactId>tomcat-embed-websocket</artifactId>
			</exclusion>
		</exclusions>
	</dependency>


프로젝트 게시 서버가 부두인 경우 나가서 좌회전할 수 있습니다. 이 블로그는 해당되지 않습니다. 이 블로그에 작성된 코드는 자체 springboot와 통합된 tomcat을 사용하여 websocket을 게시하고 추가 포트가 활성화되지 않은 것입니다! ! ! !

추천

출처blog.csdn.net/lzq2357639195/article/details/130746392