WebSocket前后端实现


websocket.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@include file="/common/common-uplan.jsp"%><script>var wsUri ="ws://localhost:8080/xbnet-product-web/websocket?username=${user.name}&userId=${user.operatorId}"; //判断浏览器是否支持websocketif(window.WebSocket){ //创建websocket连接 websocket = new WebSocket(wsUri); console.log(‘This browser supports WebSocket‘);}else{ console.log(‘This browser does not supports WebSocket‘);}//连接成功建立的回调方法websocket.onopen = function() { writeToScreen("webSocket连接成功"); }; //连接关闭的回调方法 websocket.onclose = function() { writeToScreen("webSocket连接关闭"); }; //接收到消息的回调方法websocket.onmessage = function(event) { writeToScreen(event.data);}; //连接发生错误的回调方法websocket.onerror = function() { writeToScreen("WebSocket连接发生错误");}; //关闭WebSocket连接function closeWebSocket() { websocket.close();} function doSend() { var text = $("#text") .val(); var users = $(‘input:checkbox:checked‘); var touser = ""; if (users.length == 0){ alert("请选择发送人!"); return; } else{ for (var i = 0; i < users.length; i++){ touser += users[i].value + "|"; } } if (text != "" && text != undefined && text != null){ var obj = null; obj = { toUser:touser, fromUser:"${user.operatorId}", msg:text }; obj = JSON.stringify(obj); websocket.send(obj); $("#text") .val(""); }} function writeToScreen(message) { var output = document.getElementById(‘output‘); var pre = document.createElement("p"); pre.style.wordWrap = "break-word"; pre.innerHTML = message; output.appendChild(pre); } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。window.onbeforeunload = function () { closeWebSocket();}</script><div id="main"> <div id="left" style="width: 350px;height: 280px;float: left;"> <!-- 消息显示栏 --> <div id="output" style="width: 350px;height: 240px"></div><hr/> <!-- 消息发送栏 --> <input id="text" type="text"/> <button onclick="doSend()">发送消息</button> </div> <!-- 用户列表 --> <div class="up-form-group up-col-sm-24" style="width: 100px;height: 280px;float: right;border-left:1px solid gray"> <c:forEach items="${operator }" var="rowdata" varStatus="status"> <div class="up-col-sm-24"> <label class="u_check"> <input id="" value="${rowdata.operatorId }" type="checkbox"> <i class="up-text-primary icon-u-check-empty"></i>${rowdata.name } </label> </div> </c:forEach> </div></div> 


WebSocket.java

package com.eshore.security.controller;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.net.URLDecoder;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;import javax.websocket.OnClose;import javax.websocket.OnError;import javax.websocket.OnMessage;import javax.websocket.OnOpen;import javax.websocket.Session;import javax.websocket.server.ServerEndpoint;import com.alibaba.fastjson.JSON;/** * webSocket * @author renb * @creatDate 2018年2月22日 */ // @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端, // 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端@ServerEndpoint("/websocket")public class WebSocket { // 静态变量,用来记录当前在线连接数。 private static int onlineCount = 0; // concurrent包的线程安全Map,用来存放每个客户端对应的回话信息。 private static ConcurrentMap<String, Session> webSocketMap = new ConcurrentHashMap<String, Session>(); private String userName; //当前用户 private String userId; //当前用户id,作为webSocketMap科key /** * 连接建立成功调用的方法 * * @param session * 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据 */ @OnOpen public void onOpen(Session session) { String str = session.getQueryString(); //可以得到ws://路径?后面的所有字符串 userName = str.split("&")[0].split("=")[1]; userId = str.split("&")[1].split("=")[1]; try { userName = URLDecoder.decode(userName, "utf-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } webSocketMap.put(userId, session); // 加入map中 addOnlineCount(); // 在线数加1 System.out.println("有新连接加入!当前在线人数为" + getOnlineCount()); } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { webSocketMap.remove(userId); // 从map中删除 subOnlineCount(); // 在线数减1 System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount()); } /** * 收到客户端消息后调用的方法 * * @param message * 客户端发送过来的消息 * @param session * 可选的参数 */ @SuppressWarnings("rawtypes") @OnMessage public void onMessage(String message, Session session) { System.out.println(userName + ":" + message); Map maps = (Map) JSON.parse(message); Map<String, String> resultMap = new HashMap<String, String>(); for (Object map : maps.entrySet()) { String key = (String) ((Map.Entry) map).getKey(); String value = (String) ((Map.Entry) map).getValue(); resultMap.put(key, value); } String msg = userName + ":" + resultMap.get("msg"); String toUsers = resultMap.get("toUser"); String fromUser = resultMap.get("fromUser"); String[] users = toUsers.split("\\|"); try { webSocketMap.get(fromUser).getBasicRemote().sendText(msg); Set<String> set = webSocketMap.keySet(); List<String> userList = new ArrayList<String>(); for (String str : set) { userList.add(str); } if (users.length > 0) { for (int i = 0; i < users.length; i++) { if (userList.contains(users[i])) { webSocketMap.get(users[i]).getBasicRemote().sendText(msg); } } } } catch (IOException e) { e.printStackTrace(); } } /** * 发生错误时调用 * * @param session 会话 * @param error 异常 */ @OnError public void onError(Session session, Throwable error) { System.out.println("发生错误"); error.printStackTrace(); } public static synchronized int getOnlineCount() { return onlineCount; } /** * * @creatUser renb * @creatDate 2018年2月22日 * */ public static synchronized void addOnlineCount() { WebSocket.onlineCount++; } /** * * @creatUser renb * @creatDate 2018年2月22日 * */ public static synchronized void subOnlineCount() { WebSocket.onlineCount--; } }

相关文章