websocket概念与操作

websocket的概念:

https://www.liaoxuefeng.com/wiki/1022910821149312/1103303693824096

websocket的操作:

一般现在使用websocket的工程都为springboot,所以此篇教程在springboot基础上集成。spring框架本身就实现了一个websocket子项目,只需要引入pom文件
pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

然后需要编写一个配置类,开启websocket的支持

@Configuration
public class WebSocketConfig {

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

}

然后需要封装一个WebSocket类,供其他方法调用此类的发送信息的方法。

@ServerEndpoint(value = "/project/socket/{userId}")
@Component
public class WebSocket {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocket.class);

    private static final ConcurrentHashMap<String, Session> userSessionMap = new ConcurrentHashMap<>();

    private String userId = "0";

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {

        userSessionMap.put(userId, session);
        if (userId.equals("undefined")) {
            this.userId = "0";
        } else {
            this.userId = userId;
        }

    }

    @OnMessage
    public void onMessage(String message) {
        LOGGER.info(String.format("接收到的消息为 %s", message));
        sendMessage(message, Integer.valueOf(userId));
    }

    @OnClose
    public void onClose() {
        userSessionMap.remove(userId);
        LOGGER.info("disConnect userId is {}", userId);
    }

    @OnError
    public void onError(Throwable error) {
        LOGGER.error(error.getMessage(), error);
    }


    /**
     *  封装发送信息的方法,当需要发送信息时,其他类的方法可调用此静态方法
     * @param message
     * @param userId
     */
    public static void sendMessage(String message, int userId) {
        String userIdStr = String.valueOf(userId);
        Session session = userSessionMap.get(userIdStr);
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            LOGGER.error("===========SocketServer send message error", e);
        }
//        userSessionMap.forEach((k, v) -> {
//            if (k.equals(userIdStr)) {
//                synchronized (v) {
//                    try {
//                        v.getBasicRemote().sendText(message);
//                    } catch (Exception e) {
//                        LOGGER.error("===========SocketServer send message error", e);
//                    }
//                }
//            }
//        });
    }
}
使用springboot的唯一区别是要@Component声明下,而使用独立容器是由容器自己管理websocket的,但在springboot中连容器都是spring管理的。虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。

推荐阅读更多精彩内容