zoukankan      html  css  js  c++  java
  • WebSocket实现Web聊天室

    一.客户端:

    JS代码如下:

    /*
     *     这部分js将websocket封装起来
     */
        var websocket = null;
        //判断当前浏览器是否支持WebSocket
        if ('WebSocket' in window) {
            websocket = new WebSocket("ws://localhost:8080/GoodMan/ChatService");
        }
        else {
            alert('当前浏览器 Not support websocket')
        }
        
          //连接成功建立的回调方法
        websocket.onopen = function () {
            alert("WebSocket连接成功");
        }
    
        //连接发生错误的回调方法
        websocket.onerror = function () {
            alert("WebSocket连接发生错误");
        };
        
          //发送消息
        function sendMess(content) {
             var json ="{'username':'"+'${sessionScope.username }'+"', 'content':'"+content+"'}";
            websocket.send(json);
        }
    
        //接收到消息的回调方法
        websocket.onmessage = function (event) {
            var jsonString = event.data;        //接收到的信息存放在event.data中
            var data = JSON.parse(jsonString);    //将json字符串转换成js对象
            //  然后输出data
        }
    
          //连接关闭的回调方法
        websocket.onclose = function () {
            alert("WebSocket连接关闭");
        }
    
        //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
        window.onbeforeunload = function () {
            closeWebSocket();
        }
    
        //关闭WebSocket连接
        function closeWebSocket() {
            websocket.close();
        }

    二.服务器:

    import java.io.IOException;
    import java.util.Date;
    import java.util.HashSet;
    import java.util.Set;
    import javax.websocket.*;
    import javax.websocket.server.ServerEndpoint;
    import com.google.gson.Gson;
    
    class Mess{        //封装一条消息
        private String username;
        private String content;
        private String date;
        public Mess(String username, String content, String date) {
            super();
            this.username = username;
            this.content = content;
            this.date = date;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getContent() {
            return content;
        }
        public void setContent(String content) {
            this.content = content;
        }
        public String getDate() {
            return date;
        }
        public void setDate(String date) {
            this.date = date;
        }
    }
    
    @ServerEndpoint("/ChatService")
    public class ChatService {            //每进入一个用户,就新建一个ChatService对象
        
        private static int onlineCount = 0;  //静态变量, 用来记录当前在线连接数
        private static Set<ChatService> webSocketSet = new HashSet<>();        //静态变量,用来存放在线用户
        private Session session;     //用于存储与该用户的会话,要通过它来给客户端发送数据
    
        /**
         * 连接建立成功调用的方法
         * @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
         */
        @OnOpen
        public void onOpen(Session session){
            this.session = session;
            webSocketSet.add(this);     //加入set中
            addOnlineCount();           //在线数加1
            System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
        }
        
        /**
         * 连接关闭调用的方法
         */
        @OnClose
        public void onClose(){
            webSocketSet.remove(this);  //从set中删除
            subOnlineCount();           //在线数减1
            System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
        }
    
        /**
         * 收到客户端消息后调用的方法
         * @param message 客户端发送过来的消息
         * @param session 可选的参数
         */
        @OnMessage
        public void onMessage(String data, Session session) {
            Mess mess = new Gson().fromJson(data, Mess.class);
            System.out.printf("来%s的消息:%s
    ", mess.getUsername(), mess.getContent());
            //群发消息
            for(ChatService item: webSocketSet){
                try {
                    item.sendMessage(mess);
                } catch (IOException e) {
                    e.printStackTrace();
                    continue;
                }
            }
        }
        
        /**
         * 发生错误时调用
         * @param session
         * @param error
         */
        @OnError
        public void onError(Session session, Throwable error){
            System.out.println("发生错误");
            error.printStackTrace();
        }
    
        //以下为辅助函数
        public void sendMessage(Mess mess) throws IOException{
    
            String datatime = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
            mess.setDate(datatime);
            String jsonInfo = new Gson().toJson(mess);        //将消息对象转换成json字符串
            this.session.getAsyncRemote().sendText(jsonInfo); //通过session异步地将信息发送到客户端上
        }
    
        public static synchronized int getOnlineCount() {
            return onlineCount;
        }
    
        public static synchronized void addOnlineCount() {
            ChatService.onlineCount++;
        }
    
        public static synchronized void subOnlineCount() {
            ChatService.onlineCount--;
        }
    }
  • 相关阅读:
    Java 5,6,7,8,9,10,11新特性
    LINUX中如何查看某个端口是否被占用
    Springboot项目全局异常统一处理
    面试笔记
    springboot几篇文章
    Mysql索引会失效的几种情况分析
    数组变成集合的方法
    集合变成数组的方法 Collections里面的方法
    list类里面的东西加锁 (手动加锁方法)
    Collections里面的一些方法
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/9544955.html
Copyright © 2011-2022 走看看