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--; ???} ???}
WebSocket前后端实现
原文地址:https://www.cnblogs.com/lovellll/p/10213901.html