• springMvc + websocket 实现点对点 聊天通信功能


    一,web - demo链接如下(tomcat-websocket):

    http://files.cnblogs.com/xiexy/websk.rar

    二, springMvc + websocket 实现点对点通信

    1,pom.xml 增加spring-websocket.jar

    1     <!-- websocket - version须和spring mvc的version保持一致,否则会        
    2     出现问题 -->
    3     <dependency>
    4        <groupId>org.springframework</groupId>
    5        <artifactId>spring-websocket</artifactId>
    6        <version>${spring.version}</version>
    7     </dependency>

    2,登陆  - login.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme() + "://"
                + request.getServerName() + ":" + request.getServerPort()
                + path + "/";
    %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <base href="<%=basePath%>">
    <title>socket - login</title>
    </head>
    <body>
    <center>
        <form action="websocket/login.do" method="post">
            <table>
                <tr>
                    <td>username:</td><td><input type="text" id="username" name="username"/></td>
                </tr>
                <tr>
                    <td colspan="2"> <input type="submit" value="登录"/></td>
                </tr>
            </table>
        </form>
    </center>
    </body>
    </html>
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.socket.TextMessage;
    
    import com.aisino.core.user.entity.User;
    
    @RequestMapping("websocket")
    @Controller
    public class UserController {
    
        @Autowired
        private MsgScoketHandle msgScoketHandle;
    
        @RequestMapping("login")
        public String login(String username, HttpServletRequest request){
            User user = new User();
            user.setReal_name(username);
            request.getSession().setAttribute("user",user);
            request.getSession().setAttribute("username", username);
            return "soket/soket";
        }
        
        
    
        @ResponseBody
        @RequestMapping("sendMsg")
        public String sendMag(String content,String toUserName){
            User user = new User();
            user.setReal_name(toUserName);
            TextMessage textMessage = new TextMessage(content);
            msgScoketHandle.sendMessageToUser(user,textMessage);
            return "200";
        }
    }

    3,点对点通信  socket - chat.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
        String path = request.getContextPath();
        String basePath = request.getScheme() + "://"
                + request.getServerName() + ":" + request.getServerPort()
                + path + "/";
    %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    
    <base href="<%=basePath%>">
    <title>socket - chat</title>
    <script type="text/javascript" src="plug-in/jquery/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="views/soket/sockjs.min.js"></script>
    </head>
     
    <body>
        当前登录用户:${username}<br>
        
        <input type="text" id="text">
        <button id="btn1" value="发送给后台">发送给后台</button>
        <button id="btn2" value="发送给其他用户">发送给其他用户</button>
        <div id="msg"></div>
    </body>
    
    <script type="text/javascript">
    $(document).ready(function() {
        var ws;
        if ('WebSocket' in window) {
            ws = new WebSocket("ws://"+window.location.host+"/robot/webSocketServer");
        } else if ('MozWebSocket' in window) {
            ws = new MozWebSocket("ws://"+window.location.host+"/robot/webSocketServer");
        } else {
            //如果是低版本的浏览器,则用SockJS这个对象,对应了后台“sockjs/webSocketServer”这个注册器,
            //它就是用来兼容低版本浏览器的
            ws = new SockJS("http://"+window.location.host+"/robot/sockjs/webSocketServer");
        }
        ws.onopen = function (evnt) {
        };
        //接收到消息
        ws.onmessage = function (evnt) {
            alert(evnt.data);
            $("#msg").html(evnt.data);
        };
        ws.onerror = function (evnt) {
            console.log(evnt)
        };
        ws.onclose = function (evnt) {
        }
    
        $("#btn1").click(function () {
            ws.send($("#text").val());
        });
        $("#btn2").bind("click",function () {
            var url = "${pageContext.request.contextPath}/websocket/sendMsg";
            var content =  $("#text").val();
            var toUserName = "laoliu";//与老刘通信
            $.ajax({
                data: "content=" + content + "&toUserName=" + toUserName,
                type: "get",
                dataType: 'text',
                async: false,
                contentType: "application/x-www-form-urlencoded;charset=UTF-8",
                encoding: "UTF-8",
                url: url,
                success: function (data) {
                    alert(data.toString());
                },
                error: function (msg) {
                    alert(msg);
                },
    
            });
    
        })
    });
    </script>
    </html>
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.springframework.web.socket.WebSocketHandler;
    import org.springframework.web.socket.config.annotation.EnableWebSocket;
    import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
    import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
    
    @Configuration
    @EnableWebMvc
    @EnableWebSocket
    public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{
    
        private static final Logger logger = LoggerFactory.getLogger(WebSocketConfig.class);
        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
            System.out.println("==========================注册socket");
            //注册websocket server实现类,"/webSocketServer"访问websocket的地址
            registry.addHandler(msgSocketHandle(),
                    "/webSocketServer").
                    addInterceptors(new WebSocketHandshakeInterceptor());
            //使用socketjs的注册方法
            registry.addHandler(msgSocketHandle(),
                    "/sockjs/webSocketServer").
                    addInterceptors(new WebSocketHandshakeInterceptor())
                    .withSockJS();
        }
    
         /**
         *
         * @return 消息发送的Bean
         */
        @Bean(name = "msgSocketHandle")
        public WebSocketHandler msgSocketHandle(){
            return new MsgScoketHandle();
        }
    }
    import java.util.Map;
    
    import javax.servlet.http.HttpSession;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.http.server.ServerHttpRequest;
    import org.springframework.http.server.ServerHttpResponse;
    import org.springframework.http.server.ServletServerHttpRequest;
    import org.springframework.web.socket.WebSocketHandler;
    import org.springframework.web.socket.server.HandshakeInterceptor;
    
    import com.aisino.core.user.entity.User;
    
    public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {
       private static final Logger logger = LoggerFactory.getLogger(WebSocketHandshakeInterceptor.class);
    
        /**
         * 握手前
         * @param request
         * @param response
         * @param webSocketHandler
         * @param attributes
         * @return
         * @throws Exception
         */
        @Override
        public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler webSocketHandler, Map<String, Object> attributes) throws Exception {
            logger.info("握手操作");
            if (request instanceof ServletServerHttpRequest){
               ServletServerHttpRequest servletServerHttpRequest = (ServletServerHttpRequest) request;
               HttpSession session = servletServerHttpRequest.getServletRequest().getSession(false);
               if(session != null){
                    //从session中获取当前用户
                   User user = (User) session.getAttribute("user");
                   attributes.put("user",user);
               }
           }
    
            return true;
        }
    
        /**
         * 握手后
         * @param serverHttpRequest
         * @param serverHttpResponse
         * @param webSocketHandler
         * @param e
         */
        @Override
        public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
    
        }
    }
    import java.io.IOException;
    import java.util.ArrayList;
    
    import org.springframework.stereotype.Component;
    import org.springframework.web.socket.CloseStatus;
    import org.springframework.web.socket.TextMessage;
    import org.springframework.web.socket.WebSocketHandler;
    import org.springframework.web.socket.WebSocketMessage;
    import org.springframework.web.socket.WebSocketSession;
    
    import com.aisino.core.user.entity.User;
    import com.google.common.collect.Lists;
    
    @Component
    public class MsgScoketHandle implements WebSocketHandler {
    
        /**已经连接的用户*/
        private static final ArrayList<WebSocketSession> users;
    
        static {
            //保存当前连接用户
            users = Lists.newArrayList();
        }
    
        /**
         * 建立链接
         * @param webSocketSession
         * @throws Exception
         */
        @Override
        public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
            //将用户信息添加到list中
            users.add(webSocketSession);
            System.out.println("=====================建立连接成功==========================");
            User user  = (User) webSocketSession.getAttributes().get("user");
            if(user != null){
                System.out.println("当前连接用户======"+user.getReal_name());
            }
            System.out.println("webSocket连接数量====="+users.size());
        }
    
        /**
         * 接收消息
         * @param webSocketSession
         * @param webSocketMessage
         * @throws Exception
         */
        @Override
        public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
            User user = (User) webSocketSession.getAttributes().get("user");
            System.out.println("收到用户:"+user.getReal_name()+"的消息");
            System.out.println(webSocketMessage.getPayload().toString());
            System.out.println("===========================================");
    
        }
    
        /**
         * 异常处理
         * @param webSocketSession
         * @param throwable
         * @throws Exception
         */
        @Override
        public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable){
            if (webSocketSession.isOpen()){
                //关闭session
                try {
                    webSocketSession.close();
                } catch (IOException e) {
                }
            }
            //移除用户
            users.remove(webSocketSession);
        }
    
        /**
         * 断开链接
         * @param webSocketSession
         * @param closeStatus
         * @throws Exception
         */
        @Override
        public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
            users.remove(webSocketSession);
            User user = (User) webSocketSession.getAttributes().get("user");
            System.out.println(user.getReal_name()+"断开连接");
        }
    
        @Override
        public boolean supportsPartialMessages() {
            return false;
        }
    
        /**
         * 发送消息给指定的用户
         * @param user
         * @param messageInfo
         */
        public void sendMessageToUser(User user, TextMessage messageInfo){
            for (WebSocketSession session : users) {
                User sessionUser = (User) session.getAttributes().get("user");
                //根据用户名去判断用户接收消息的用户
                if(user.getReal_name().equals(sessionUser.getReal_name())){
                    try {
                        if (session.isOpen()){
                            session.sendMessage(messageInfo);
                            System.out.println("发送消息给:"+user.getReal_name()+"内容:"+messageInfo);
                        }
                        break;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    4,注意点,使用Tomcat8以上,tomcat7会报错(貌似与tomat-websocket 冲突)

     demo地址:https://files.cnblogs.com/files/xiexy/springMvc-websocket.zip

  • 相关阅读:
    你有认真了解过自己的“Java对象”吗? 渣男
    布隆过滤器,你也可以处理十几亿的大数据
    阻塞队列——手写生产者消费者模式、线程池原理面试题真正的答案
    Java集合面试题汇总篇
    Github 骚操作
    责任链模式——更灵活的if else
    时间复杂度到底怎么算
    创造DotNet Core轻量级框架【二】
    创造DotNet Core轻量级框架【一】
    小胖李的面试之旅(二)
  • 原文地址:https://www.cnblogs.com/xiexy/p/4070562.html
Copyright © 2020-2023  润新知