java-websocket即时通讯-聊天室
来源:互联网 发布:微信无法连接网络 编辑:程序博客网 时间:2024/06/08 09:40
效果预览
web即时通讯的解决方式
- 轮询:简单粗暴,过多的请求,服务器表示压力很大
- 长连接:发送请求到服务器,有消息时才返回,长时间占用资源
websocket:基于tcp新的协议,双向通信
废话少说,上代码(部分关键代码)!
html
<style> #chatroom_container{width:600px;height:500px;margin:70px auto 0px auto;background:#fff;border-radius:4px;overflow:hidden;box-shadow:0px 0px 20px #666;} #east{float:right;width:130px;height:350px;} #center{float:left;width:469px;height:350px;box-sizing:border-box;padding:8px;border-right:1px solid #ddd;overflow-y:auto;} #south{width:100%;height:40px;border-top:1px solid #ddd;position:absolute;left:0;bottom:0;box-sizing:border-box;padding:10px;background:#fff;} #chat{width:100%;height:100%;box-sizing:border-box;} #sendButton{position:absolute;bottom:5px;right:6px;} .record{margin:6px 5px;} .onlineStaff{margin:3px 4px;padding:3px 4px;cursor:pointer;} .onlineStaff:hover{background:#f0f0f0;}</style><div id="chatroom_container"> <div id="north">交流平台</div> <div id="online"></div> <div id="center"> <div id="console"></div> </div> <div id="east"></div> <div style="clear:both;"></div> <div id="south"> <textarea id="chat" ></textarea> <div id="sendButton" onclick="Chat.sendMessage()">发送</div> </div></div>
js
var Chat = {};Chat.socket = null;Chat.connect = (function(host){ if ('WebSocket' in window) { Chat.socket = new WebSocket(host); } else if ('MozWebSocket' in window) { Chat.socket = new MozWebSocket(host); } else { Console.log('Error: WebSocket is not supported by this browser.'); return; } //websocket连接打开时 Chat.socket.onopen = function () { document.getElementById('chat').onkeydown = function(event) { if (event.keyCode == 13) { Chat.sendMessage(); event.returnValue = false; event.preventDefault(); } }; }; //websocket连接关闭时 Chat.socket.onclose = function () { document.getElementById('chat').onkeydown = null; }; //websocket连接有消息时 Chat.socket.onmessage = function (message) { var data = eval('(' + message.data + ')'); //data即为后台发送的数据,在此根据数据内容进行判断属于Chat.info | Chat.self | Chat.other }});//初始化Chat.initialize = function() { if (window.location.protocol == 'http:') { Chat.connect('ws://' + window.location.host + '/websocket/chat'); } else { Chat.connect('wss://' + window.location.host + '/websocket/chat'); }};//发送的方法Chat.sendMessage = (function() { var message = document.getElementById('chat').value; if (message != '') { var data = { 'from':'', 'to':'', 'groupId':'', 'type':'', 'message':message }//from,to,type为后期私聊,群里 var msg = JSON.stringify(data); Chat.socket.send(msg); document.getElementById('chat').value = ''; }});var Console = {};//聊天主窗体//负责展现系统提示,例如 小明进入Console.info = (function(message) { var h = '<div style="text-align:center;color:#aca;margin:5px auto;">'+ message +'</div>'; $('#center').append(h);});//负责展现自己发送的消息,显示在右边Console.self=(function(data){ var h = ''; //将data解析为html片段 $('#center').append(h);});//负责展现其他人发送的消息,显示在左边Console.other=(function(data){ var h = ''; //将data解析为html片段 $('#center').append(h);});Chat.initialize();
java后台
- 核心处理类ChatWebSocket.java,负责websocket连接/关闭/收发消息的整个过程
- 消息类WebSocketMessage.java,发送消息的载体
- 消息处理类ServerEncoder.java,将消息进行编码转json设置
- 配置类GetHttpSessionConfigurator.java,获取httpSession
ChatWebSocket.java
websocket连接/关闭/收发消息的整个过程
@ServerEndpoint(value = "/websocket/chat", configurator = GetHttpSessionConfigurator.class, encoders = ServerEncoder.class)public class ChatWebSocket { //存储所有的websocket连接 private static final Map<String, ChatWebSocket> CONNECTIONS = new LinkedHashMap<String, ChatWebSocket>(); private User user; private Session session; /** * 当websocket握手成功时触发 * 该方法参数是可选的,session指的是websocket的session,不是httpSession. * 获取httpSession需要通过EndpointConfig类,而EndpointConfig类是由@ServerEndpoin()中的configurator进行设置 */ @OnOpen public void start(Session session, EndpointConfig config){ this.session = session; HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName()); WebSocketMessage webSocketMessage = new WebSocketMessage(); if(httpSession == null){ webSocketMessage.setMessage("您未登录系统"); ChatWebSocket.sendToOne(this,webSocketMessage); try { this.session.close(); } catch (IOException e) { e.printStackTrace(); } }else{ //获取httpSession中登录的用户 User user = (User) httpSession.getAttribute("currentUser"); if(user == null){ webSocketMessage.setMessage("登录错误,未知用户"); ChatWebSocket.sendToOne(this,webSocketMessage); try { this.session.close(); } catch (IOException e) { e.printStackTrace(); } }else{ this.user = user; CONNECTIONS.put(this.user.getId(), this); webSocketMessage.setUserId(this.user.getId()); ChatWebSocket.sendToOne(this,webSocketMessage); String msg = this.user.getName() + " 进入"; ChatWebSocket.broadcastOnline(msg); } } } //当websocket握手关闭时触发 @OnClose public void end(){ CONNECTIONS.remove(this.user.getId()); String msg = this.user.getName() + " 离开"; ChatWebSocket.broadcastOnline(msg); } //当收到消息时 @OnMessage public void incoming(String message){ WebSocketMessage webSocketMessage = new WebSocketMessage(); webSocketMessage.setUserId(this.user.getId()); webSocketMessage.setUserName(this.user.getName()); webSocketMessage.setMessage(message); webSocketMessage.setSendDate(new Date()); ChatWebSocket.broadcast(webSocketMessage); } //发送至单独用户 private static void sendToOne(ChatWebSocket chatWebSocket, WebSocketMessage webSocketMessage) { chatWebSocket.session.getAsyncRemote().sendObject(webSocketMessage); } //广播 private static void broadcast(WebSocketMessage webSocketMessage) { Set<String> keys = CONNECTIONS.keySet(); for (String key : keys) { ChatWebSocket chatWebSocket = CONNECTIONS.get(key); synchronized (chatWebSocket) { ChatWebSocket.sendToOne(chatWebSocket, webSocketMessage); } } } //广播在线用户 private static void broadcastOnline(String msg) { Set<String> keys = CONNECTIONS.keySet(); WebSocketMessage webSocketMessage = new WebSocketMessage(); webSocketMessage.setType(WebSocketMessage.WEBSOCKETMESSAGE_TYPE_ALL); webSocketMessage.setMessage(msg); List<UserAO> userList = new ArrayList<UserAO>(); for (String key : keys) { ChatWebSocket chatWebSocket = CONNECTIONS.get(key); userList.add(chatWebSocket.user); } webSocketMessage.getAttributes().put("user", userList); for (String key : keys) { ChatWebSocket chatWebSocket = CONNECTIONS.get(key); synchronized (chatWebSocket) { ChatWebSocket.sendToOne(chatWebSocket, webSocketMessage); } } }}
WebSocketMessage.java
发送消息的载体
public class WebSocketMessage { private String userId; private String userName; private string from; private string to; private string groupId; ... private String message; private Date sendDate; private String type; private Map<String,Object> attributes = new HashMap<String, Object>(); public WebSocketMessage(){ super(); } public WebSocketMessage(String userName,String message,Date sendDate) { this.userName = userName; this.sendDate = sendDate; this.message = message; } //getter and setter ...}
ServerEncoder.java
将消息进行编码转json设置
public class ServerEncoder implements Encoder.Text<WebSocketMessage> { @Override public void init(EndpointConfig paramEndpointConfig) { // TODO Auto-generated method stub } @Override public void destroy() { // TODO Auto-generated method stub } @Override public String encode(WebSocketMessage paramT) throws EncodeException { //将WebSocketMessage转为json return JsonMapper.buildNormalMapper().toJson(paramT); }}
GetHttpSessionConfigurator
获取httpSession
public class GetHttpSessionConfigurator extends Configurator { @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { HttpSession httpSession=(HttpSession) request.getHttpSession(); if(httpSession!=null){ sec.getUserProperties().put(HttpSession.class.getName(),httpSession); } }}
以上只是部分关键代码,简单的实现了即时通讯,若需要私聊,群聊,分组等功能,则需改造WebSocketMessage.java和前端js中Chat.socket.onmessage()
阅读全文
0 0
- java-websocket即时通讯-聊天室
- JavaWeb网页聊天室(WebSocket即时通讯)
- Java webSocket 网页聊天室
- Java WebSocket 聊天室Demo
- Java、WebSocket、HTML简易聊天室
- java websocket 建立一个聊天室
- websocket即时通讯java SpringMVC mybatis 后台框架
- WebSocket 聊天室
- WebSocket聊天室
- websocket聊天室
- websocket聊天室
- websocket聊天室
- Java和WebSocket开发网页聊天室
- Java WebSocket实现网络聊天室(群聊+私聊)
- Java WebSocket编程与网页简易聊天室
- Java和WebSocket开发网页聊天室
- Java WebSocket实现网络聊天室(群聊+私聊)
- Java WebSocket实现网络聊天室(群聊+私聊)
- WCF、WebAPI、WebService之间的区别
- linux内核空间和用户空间详解
- 命名规则(零)-Unfinished
- 计算两点间的距离
- 深度学习入门必须理解这25个概念
- java-websocket即时通讯-聊天室
- HDU 3033 I love sneakers! (分组背包)
- 浏览器缓存之Last-Modified
- 1.2 python入门学习之mac开发工具
- Android中事件的分发与处理流程
- 软件调试笔记19
- ORA-01187,ORA-01110报错
- 水池数目
- Java算法面试题(004) 实现一个算法来确定一个字符串是否具有所有唯一的字符