• websocket的使用


    依赖包    

     <!--实时通信的依赖包-->
          <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.1</version>
            <scope>provided</scope>
          </dependency>

    开发一个服务端程序用来广播消息

      实体类

    package com.seecen.ws;
    
    /**
     * Author: CalcYu
     * Date: 2019/8/12
     */
    public class Message {
        //-1: 群聊 2:私聊 0:系统 999:特殊操作
        private int type;
    
        //内容
        private String content;
    
        //私聊接收者
        private Integer toUser;
    
    
        public int getType() {
            return type;
        }
    
        public void setType(int type) {
            this.type = type;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public Integer getToUser() {
            return toUser;
        }
    
        public void setToUser(Integer toUser) {
            this.toUser = toUser;
        }
    }

      特效实体类

    package com.seecen.ws;
    
    /**
     * Author: CalcYu
     * Date: 2019/8/13
     */
    public class Msg {
        /**
         * 1:系统上/下线消息
         * 4:用户文本消息
         * 5:收到用户抖动消息
         * 6:收到用户撤回消息
         */
        private int type;
        private String username;
        private int messageId;
        private String content;
    
        public Msg() {
        }
    
        public Msg(int type, String username, int messageId, String content) {
            this.type = type;
            this.username = username;
            this.messageId = messageId;
            this.content = content;
        }
    
        public int getType() {
            return type;
        }
    
        public void setType(int type) {
            this.type = type;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public int getMessageId() {
            return messageId;
        }
    
        public void setMessageId(int messageId) {
            this.messageId = messageId;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    }

    给websocket服务定义一个连接的地址

    package com.seecen.ws;
    
    import com.alibaba.fastjson.JSON;
    import com.seecen.controller.LoginController;
    import com.seecen.entity.User;
    
    import javax.servlet.http.HttpSession;
    import javax.websocket.*;
    import javax.websocket.server.ServerEndpoint;
    import java.io.IOException;
    import java.util.concurrent.CopyOnWriteArraySet;
    
    /**
     * Author: CalcYu
     * Date: 2019/8/9
     * 1.客户端建立连接
     * 2.客户端断开连接
     * 3.客户端发送消息
     */
    //给websocket服务定义一个连接的地址
    //ws:localhost:8080/my_chat
    @ServerEndpoint(value = "/my_chat", configurator = GetHttpSession.class)
    public class ChatServer {
    
        //声明一个集合来保存客户断程序,建立连接或断开连接都是并发操作
        private static CopyOnWriteArraySet<ChatServer> clients = new CopyOnWriteArraySet<>();
    
        private Session session;
        //每个ChatServer绑定一个User对象
        private User user;
    
        /**
         * 当建立连接执行
         * 创建连接时会创建一个session对象
         * 每个客户端会创建 一个ChatServer对象 每个对象有一个session
         */
        @OnOpen
        public void onOpen(Session session, EndpointConfig config) {
            this.session = session;
            clients.add(this);
            //从配置文件中获取httpSession对象及User对象
            HttpSession httpSession = (HttpSession)
                    config.getUserProperties().get(HttpSession.class.getName());
            //获取httpSession中的User对象
            User user = (User) httpSession.getAttribute(LoginController.USER_INFO);
            this.user = user;
            System.out.println("有新的连接加入,当前在线人数为:" + clients.size());
        }
    
        /**
         * 当断开连接执行
         */
        @OnClose
        public void onClose() {
            clients.remove(this);
            System.out.println("有一个用户退出,当前在线人数为:" + clients.size());
        }
    
        /**
         * 当发送消息执行
         *
         * @param msg
         */
        @OnMessage
        public void onMessage(String msg) {
            //传递比较丰富的消息可以采用json
            //如果给客户端主动发送消息
            //广播
            //把字符串还原成对象
            Message message = JSON.parseObject(msg, Message.class);
            //当类型为-1时 群聊,把消息content广播给所有在线用户
            if (message.getType() == -1) {
                for (ChatServer chat : clients) {
                    try {
                        //<p style="color: green">群聊消息</p>
                        String html = "<p style='color: green'>%s</p>";
                        chat.getSession().getBasicRemote().sendText(String.format(html,message.getContent()));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            } else if (message.getType() == 2) {
                //私聊
    //            遍历集合找到对应用户进行推送(问题:并不知道哪个ChatServer对象是哪个用户)
                for (ChatServer c : clients) {
                    if (c.getUser().getUserId().intValue() == message.getToUser()) {
                        //  张三对李四说:晚上吃什么?
                        //<p style="color: red">私聊消息</p>
                        String html = "<p style='color: red'>%s</p>";
                        String content = this.user.getUserName() + "对" + c.getUser().getUserName() + ":" + message.getContent();
                        try {
                            c.getSession().getBasicRemote().sendText(String.format(html, content));
                            //给自己发送消息
                            this.getSession().getBasicRemote().sendText(String.format(html, content));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        break;
                    }
                }
            }
    
        }
    
        //当websocket出错会执行
        @OnError
        public void onError(Throwable e){
            e.printStackTrace();
        }
    
        public User getUser() {
            return user;
        }
    
        //只能读取不能修改
        public Session getSession() {
            return session;
        }
    }

    开发一个客户端程序用来发送和接收消息

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .main {
                width: 350px;
                margin: 0 auto;
            }
    
            .main #msgBox {
                width: 100%;
                height: 300px;
            }
        </style>
    </head>
    <body>
    <div class="main">
        <div id="msgBox" ></div>
        <select name="" id="user">
            <option value="-1">所有人</option>
            <option value="3">张三</option>
            <option value="6">李四</option>
        </select>
        <input type="text" id="inputTxt">
        <input type="button" id="sendBtn" value="发送">
    </div>
    <script src="/js/jquery.min.js"></script>
    <script>
        //字面量的方式传递一个对象
        var obj = {userName: "1111", userPsw: "123"};
        var obj2 = new Object();
        obj2.userName = "123123";
    
        //把js对象转换成字符串
        var jsonStr = JSON.stringify(obj);
        //把字符串转换成对象
        var jsObj = JSON.parse(jsonStr);
        //同时打印多个变量值
        console.log(obj, obj2, jsonStr, jsObj);
    
    
        //当页面加载完成连接服务器程序
        var url = "ws://localhost:8866/my_chat";
        var ws = new WebSocket(url);
        if (ws) {
            //采用监听的方式来绑定回调函数
            ws.onopen = function (event) {
                console.log("连接服务器成功");
                $("#msgBox").append("连接服务器成功
    ");
            }
            ws.onclose = function (event) {
                $("#msgBox").append("服务器连接中断
    ");
            }
            ws.onmessage = function (event) {
                $("#msgBox").append(event.data + "
    ");
            }
            //主动给服务器发送消息
            $("#sendBtn").click(function () {
                var msg = $("#inputTxt").val();
                if (msg) {
                    var msgType = $("#user").val();
                    if (msgType == -1) {
                        //发送给所有人
                        var msgObj = {type: -1, content: msg};
                        ws.send(JSON.stringify(msgObj));
                    } else {
                        //私聊
                        var msgObj = {type: 2, content: msg, toUser: msgType};
                        ws.send(JSON.stringify(msgObj))
                    }
    
                }
            })
        } else {
            alert("浏览器版本过低,不支持websocket协议");
        }
    </script>
    </body>
    </html>

    websocket使用细节

    1. 如何通过json传递信息
    2. 如何把json字符串还原回一个对象  

          依赖包

            fastjson (阿里巴巴开源的) 

     <!--json转换依赖包-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.31</version>
            </dependency> 

        JSON api

          toJSONString 方法

          parseObject 方法

          parseArray 方法

        html里面转换

          js中进行互转  

    JSON.stringify(obj);
    JSON.parse(jsonStr);

        WebSocket中如何获取HttpSession对象中的User

          增加终端配置文件

    package com.seecen.ws;
    
    import javax.servlet.http.HttpSession;
    import javax.websocket.HandshakeResponse;
    import javax.websocket.server.HandshakeRequest;
    import javax.websocket.server.ServerEndpointConfig;
    
    /**
     * Author: CalcYu
     * Date: 2019/8/12
     * 自定义终端配置文件获取httpSession中的对象
     */
    public class GetHttpSession extends ServerEndpointConfig.Configurator {
        @Override
        public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
            //获取httpSession对象,保存至终端配置文件的用户属性中
            HttpSession session = (HttpSession) request.getHttpSession();
            if (session != null) {
                sec.getUserProperties().put(HttpSession.class.getName(), session);
            }
        }
    }

       web.xml中可以设置websocket文本缓存大小

     <!--设置websocket文本缓存大小-->
        <context-param>
            <param-name>org.apache.tomcat.websocket.textBufferSize</param-name>
            <param-value>5242800</param-value>
        </context-param>

     

  • 相关阅读:
    Java基础知识之设计模式--观察者模式
    Java基础知识之设计模式--工厂模式
    Java Socket应用
    Java基础知识之设计模式--单例模式
    Docker的三种网络代理配置
    Docker被禁了!只能靠它了......
    老司机带你出坑:请收下这份运维故障处理指南
    这样理解 HTTP,面试再也不用慌了~
    为什么说卷积神经网络,是深度学习算法应用最成功的领域之一?
    一文搞懂CDN加速原理
  • 原文地址:https://www.cnblogs.com/lin02/p/11480110.html
Copyright © 2020-2023  润新知