Jeff 发表于 2017-5-4 17:06:51

WebSocket优化建议

1. 加一个uid字段标识当前websocket对象,方便后续关闭时从map中移除和直接查找消息发送目标用户。
2. webSocketHashMap改为ConcurrentHashMap
3. 去掉onlineCount,获取在线人数使用websocketmap.size()

        @OnClose
        public void onClose() {
                webSocketHashMap.remove(this.uid);// webSocketHashMap.remove(this);不能从map中移除当前已关闭的websocket对象
                ...
        }

@OnMessage
        public void onMessage(String message, Session session) {
                logger.debug("来自客户端的消息:" + message);
                JSONObject json = JSON.parseObject(message);
                JSONObject jsonObject = (JSONObject) json.get("data");
                String to = jsonObject.get("to").toString();
               
                try {
                        if (webSocketHashMap.containsKey(to)) { // for (String key : webSocketHashMap.keySet()) { ... }
                                ((WebSocket) webSocketHashMap.get(to))
                                                .sendMessage(message);
                        }

                } catch (Exception e) {
                        e.printStackTrace();
                }
        }

完整代码:

package com.jeecg.chat.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeecg.chat.entity.ChatMessageHistory;
import com.jeecg.chat.service.ChatMessageHistoryService;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.jeecgframework.p3.core.logger.Logger;
import org.jeecgframework.p3.core.logger.LoggerFactory;
import org.jeecgframework.p3.core.utils.common.ApplicationContextUtil;
import org.springframework.context.ApplicationContext;

@ServerEndpoint("/WebSocket/{id}")
public class WebSocket {
        private static final Logger logger = LoggerFactory.getLogger(WebSocket.class);

        private static Map<String, WebSocket> webSocketHashMap = new ConcurrentHashMap<String, WebSocket>();
       
        private Session session;
        private String uid;
       
        private ChatMessageHistoryService chatMessageHistoryService;

        @OnOpen
        public void onOpen(@PathParam("id") String id, Session session) {
                this.session = session;
                this.uid = id;
                webSocketHashMap.put(id, this);

                logger.info("有新连接加入!当前在线人数为" + getOnlineCount());

                ApplicationContext ctx = ApplicationContextUtil.getContext();
                if (ctx.containsBean("chatMessageHistoryService"))
                        this.chatMessageHistoryService = ((ChatMessageHistoryService) ctx
                                        .getBean("chatMessageHistoryService"));
        }

        @OnClose
        public void onClose() {
                webSocketHashMap.remove(this.uid);
                logger.info("有一连接关闭!当前在线人数为" + getOnlineCount());
        }

        @OnMessage
        public void onMessage(String message, Session session) {
                logger.debug("来自客户端的消息:" + message);
                JSONObject json = JSON.parseObject(message);
                JSONObject jsonObject = (JSONObject) json.get("data");
                String to = jsonObject.get("to").toString();
               
                ChatMessageHistory messageHistory = new ChatMessageHistory();
                messageHistory.setFromName(jsonObject.getString("fromName"));
                messageHistory.setFromUser(jsonObject.getString("from"));
                messageHistory.setToName(jsonObject.getString("toName"));
                messageHistory.setToUser(jsonObject.getString("to"));
                messageHistory.setMsgType(json.getString("type"));
                messageHistory.setMsg(jsonObject.getString("msg"));
                String randomSeed = UUID.randomUUID().toString().replaceAll("-", "")
                                .toUpperCase();
                messageHistory.setId(randomSeed);
                this.chatMessageHistoryService.insert(messageHistory);
                messageHistory = null;
                try {
                        if (webSocketHashMap.containsKey(to)) {
                                ((WebSocket) webSocketHashMap.get(to))
                                                .sendMessage(message);
                        }

                } catch (Exception e) {
                        e.printStackTrace();
                }
        }

        @OnError
        public void onError(Session session, Throwable error) {
                logger.info("发生错误");
                error.printStackTrace();
        }

        public void sendMessage(String message) throws IOException {
                this.session.getBasicRemote().sendText(message);
        }

        public static synchronized int getOnlineCount() {
                return webSocketHashMap.size();
        }

}


jeecgadmin 发表于 2017-5-8 19:14:27

你的在线聊天功能可以了吗?求指导!

Jeff 发表于 2017-5-9 10:12:56

我按这个帖子做的:http://jeecg.iteye.com/blog/2320670
集成步骤:
1、pom.xml 引入{聊天插件}依赖   
 
Java代码  

        1. <!-- 在线聊天工具  -->  
        2. <dependency>  
        3. <groupId>org.p3framework</groupId>  
        4. <artifactId>jeecg-p3-biz-chat</artifactId>  
        5. <version>1.0.0</version>  
        6. <type>jar</type>  
        7. <scope>compile</scope>  
        8. </dependency>  
 
2、增加聊天websocket配置文件:config.js
 
    路径位置:src/main/webapp/plug-in/layim/config.js
    修改websocket ip配置:
 
Java代码  

        1. var chatIp = "192.168.0.113";  
 
3、增加文件:layui.jsp
    路径:src/main/webapp/context/layui.jsp
 
4、首页引入通用layui.jsp
    修改文件:src/main/webapp/webpage/main/hplus_main.jsp
    代码修改位置:652行,新增如下代码:
 
Java代码  

        1. <!-- 在线聊天 -->  
        2. <%@include file="/context/layui.jsp"%>  
 
5、项目启动,需要采用tomcat7(tomcat6不支持websocket)


但是感觉这个功能跟cookie关联有点大而且容易出错,浏览器先后登录不同用户名后,点击分组和用户都会报js错,无法正常使用该功能。需要清除缓存后重新登录可以发送消息,或者直接使用chrome的隐身模式比较好使一点。
页: [1]
查看完整版本: WebSocket优化建议