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}"; //判断浏览器是否支持websocket
if(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前后端实现的更多相关文章

  1. websocket+前后端分离+https的nginx配置

    后端服务路径: 172.168.0.2:8080 172.168.0.2:7080 前端目录(html + css + js): /root/apps/mzsg-web 1.修改 /etc/nginx ...

  2. 9、socket.io,websocket 前后端实时通信,(聊天室的实现)

    websocket 一种通信协议 ajax/jsonp 单工通信 websocket 全双工通信 性能高 速度快 2种方式: 1.前端的websocket 2.后端的 socket.io 一.后端so ...

  3. 基于node.js的websocket 前后端交互小功能

    一.node var ws = require("nodejs-websocket"); console.log("开始建立连接...") var server ...

  4. 前后端常用通讯方式-- ajax 、websocket

    一.前后端常用通讯方式 1. ajax  浏览器发起请求,服务器返回数据,服务器不能主动返回数据,要实现实时数据交互只能是ajax轮询(让浏览器隔个几秒就发送一次请求,然后更新客户端显示.这种方式实际 ...

  5. WebSocket实现前后端通讯

    WebSocket实现前后端通讯 长安如梦里,何日是归期. 简介:我们上线了一个商城项目,移交运营团队使用之后,他们要求商城有新订单来的时候同时加上声音提示,让她们可以及时知道有单来了.我这边想了想, ...

  6. 基于SuperSocket实现的WebSocket(后端)

    关于WebSocket其实很早就想发了,奈何之前项目中的WebSocket的后端不是我做的,而我又想前后端都发出来和大家讨论讨论~于是挤出点时间研究了一下WebSocket的后端实现(所以才有了这篇文 ...

  7. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十一║Vue实战:开发环境搭建【详细版】

    缘起 哈喽大家好,兜兜转转终于来到了Vue实战环节,前边的 6 篇关于Vue基础文章我刚刚简单看了看,感觉写的还是不行呀,不是很系统,所以大家可能看上去比较累,还是得抽时间去润润色,修改修改语句和样式 ...

  8. 从零开始搭建django前后端分离项目 系列一(技术选型)

    前言 最近公司要求基于公司的hadoop平台做一个关于电信移动网络的数据分析平台,整个项目需求大体分为四大功能模块:数据挖掘分析.报表数据查询.GIS地理化展示.任务监控管理.由于页面功能较复杂,所以 ...

  9. 如何简单区分Web前后端与MVC

    MVC是开发所有软件所必须涉及的基本几个划分 M主要负责数据与模型,V主要负责显示C主要负责交互与业务所以不管是前端还是后端,都是有MVC的.MVC是一个对于软件简单的抽象,不管是M还是V,还是C都是 ...

随机推荐

  1. Joomla - 部署(线上部署)

    一.线上部署 线上部署可以理解为把本地网站迁移到线上,使用 akeeba backup 进行备份和迁移即可 参考 Joomla - akeeba backup(joomla网站备份.迁移扩展)的第三. ...

  2. 08_jQuery对象初识(四)each循环、data(非常重要)

    each: 不使用for循环答应jQuery对象,使用each: 退出整个each循环: 退出一次each循环: data:

  3. js 属性的遍历

    引自:http://es6.ruanyifeng.com/#docs/object 属性的遍历 ES6 一共有5种方法可以遍历对象的属性. (1)for...in for...in循环遍历对象自身的和 ...

  4. hdfs写并发问题

    hdfs文件写入不支持多个进程同时写入一个文件,每次只能一个FS挟持对象的人写入

  5. Netty TCP粘包/拆包问题《一》

    1.使用LineBasedFrameDecoder,StringDecoder解析器进行解决TCP粘包/拆包问题 2.代码搞起: TimeClient:客户端 /* * Copyright 2013- ...

  6. Grep- Linux必学的60个命令

    1.作用 grep命令可以指定文件中搜索特定的内容,并将含有这些内容的行标准输出.grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所 ...

  7. nowcoder牛客wannafly挑战赛20

    A---染色 签到题,设最终颜色为x,一次操作就需要把一个不是x的点变为x,所以最终颜色为x时需要操作 总结点个数-颜色为x的节点个数,然后枚举所有颜色就行了 #include <iostrea ...

  8. 关于dictionary和tuple充当函数参数

    需要接收dict时,使用 **name: 需要接收tuple时,使用 *name: --> *name参数后面的任何数据会被认为是’keyword-only’,即它们只能被当作关键词而非参数使用 ...

  9. HZOI2019 A. 那一天我们许下约定 dp

    题目大意:https://www.cnblogs.com/Juve/articles/11219089.html 读这道题的题目让我想起了... woc我到底在想什么?好好写题解,现在不是干那个的时候 ...

  10. 101 Hack October'14

    拖了近一个月的总结.(可能源于最近不太想做事:() A题 给出n个长度都为n的字符串,你只可以对每个字符串分别排序,问当每个字符串按升序排序之后,每一列是否也是升序的. #include <cm ...