SSM+WebSocket实现一个简易网页版通讯工具

编译环境:jdk1.8 , tomcat8.0+ , IDEA

这里主要讲一下websocket的信息传递,以如何实现多人实时在线聊天为例:

websocket主要的三个类

MyWebSocketConfig主要负责配置websocket的处理器和握手拦截器

MyHandShakeInterceptor 是websocket的拦截器

MyWebSocketHander是websocket的处理器

@Component
@EnableWebSocket
public class MyWebSocketConfig implements WebSocketConfigurer {

    @Autowired
    private MyWebSocketHander myWebSocketHander;

    private static final String LINK_URI = "websocket.do";
    //添加websocket处理器,添加握手拦截器  拦截器先执行 然后到处理器
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        webSocketHandlerRegistry.addHandler(myWebSocketHander,LINK_URI).addInterceptors(new MyHandShakeInterceptor());
    }
}
/*   private static Map map = new HashMap();
 * websocket握手拦截器
 * 拦截握手前,握手后的两个切面
 */
@Component
public class MyHandShakeInterceptor implements HandshakeInterceptor {


    @Override
    public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map map) throws Exception {
        if(serverHttpRequest instanceof ServletServerHttpRequest){
            HttpServletRequest servletRequest = ((ServletServerHttpRequest)serverHttpRequest).getServletRequest();
            User user = (User)servletRequest.getSession().getAttribute("user");
            //这里给map赋值 相当于websockethandler的afterConnectionEstablished方法里的WebSocketSession
            //key是session,value是变量
            map.put("ws_user", user);
          
        }
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
      
    }
}

实时通信的具体流程:

前端

<% String path = request.getContextPath();%>

link rel="stylesheet" href="<%=path%>/static/css/bootstrap.min.css"
      type="text/css">




后台MyWebSocketHander接受数据


@Component
public class MyWebSocketHander implements WebSocketHandler {
   
    private final static List USERS = new ArrayList<>();
    private final static List USER_ONLINE = new ArrayList<>();

    /*
    *在链接创建完后就在前端显示在线用户
    */
    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
       USERS.add(webSocketSession);
        //每次有新的连接,就加入到user集合中
        User user = (User) webSocketSession.getAttributes().get("ws_user");
        USER_ONLINE.add(user);

        List userNamelist = new ArrayList<>();
        for (User u : USER_ONLINE) {
            String userName = u.getUserName();
            userNamelist.add(userName);
        }

        //String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。
        //这里传到前端的应该是JSON格式
        String messageFormat = "{onlineNum:\"%d\",userName:\"%s\" , msgTyp " +
                ":\"%s\"}";
        String msg = String.format(messageFormat, USERS.size(), userNamelist,
                "notice");

        TextMessage testMsg = new TextMessage(msg + "");
        //确保每个用户信息都能同步到
        for (WebSocketSession wss : USERS) {
            wss.sendMessage(testMsg);
        }
    }

    /**
     * 客户端发送服务器的消息时的处理函数,在这里收到消息之后可以分发消息
     */
    @Autowired
    private ChatService chatService;

    @Override
    public void handleMessage(WebSocketSession webSocketSession,
                              WebSocketMessage webSocketMessage) throws Exception {

        String messageFormat = null;

        //发送消息的时间
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String sentMsgDate = dateFormat.format(new Date());

        User user = (User) webSocketSession.getAttributes().get("ws_user");

        String msgContent = webSocketMessage.getPayload() + "";

        JSONObject chat = JSON.parseObject(msgContent);
        //消息的内容
        String msgJSON = chat.get("message").toString();
        //消息的样式
        String msgJSONType = chat.get("type").toString();

        String chatMsg = "chatMsg";
 
        if (msgJSONType.equals(chatMsg)) {
            //将消息保存到数据库
            ChatMsg chatMessage = new ChatMsg(user.getId(), sentMsgDate,
                    msgJSON);
            chatService.addMessage(chatMessage);

            messageFormat = "{user:\"%s\",sendDate:\"%s\" ," +
                    "sendContent:\"%s\" , msgTyp :\"%s\"}";
            String message = String.format(messageFormat, user.getUserName(),
                    sentMsgDate, msgJSON , "msg");
            TextMessage toMsg = new TextMessage(message + "");
            //遍历所有的用户,发信息,这个要注意哦,要不然不能做到多人同时聊天
            for (WebSocketSession wss : USERS) {
                wss.sendMessage(toMsg);
            }
        }
    }


    @Override
    public void handleTransportError(WebSocketSession webSocketSession,
                                     Throwable throwable) throws Exception {
        USERS.remove(webSocketSession);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession,
                                      CloseStatus closeStatus) throws Exception {
        User userRemove = (User) webSocketSession.getAttributes().get(
                "ws_user");
        USER_ONLINE.remove(userRemove);
        USERS.remove(webSocketSession);
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

}

所以websocket消息传送流程大致是

websocket.onopen打开链接 --> websocket.send()发送数据 -->后台的MyWebSocketHander接收数据-->WebSocketSession.sendMessage将消息发送给前端 --> 前端websocket.onmessage()接收数据并显示。

github地址:https://github.com/androidlearner2017/simple-chatroom.git

很简单的一个demon,里面有些功能还没有完全实现,继续修改中 ing

你可能感兴趣的:(conclusion)