Websocket实现前后台通信,demo小测试
新需求大概如下:用户登录系统,登录成功之后建立websocket连接,实现通信
总体思路:前端不是我负责,只是简单的做个功能,先实现登录,把用户标识存入HttpSeesion,再建立websocket连接,拦截器HandshakeInterceptor拦截请求,把用户标识存入Map<String, Object> attributes,然后处理器handler处理各种操作。
/**
* @author wangqq
* @version 创建时间:2018年11月1日 下午2:59:21
* 实现WebSocketConfigure配置自己的socket链接
*/
@Configuration //用于定义配置类,可替换xml配置文件
@EnableWebSocket
@EnableWebMvc //启动Spring MVC特性
public class WebsocketConfig implements WebSocketConfigurer { @Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// TODO Auto-generated method stub
registry.addHandler(handler(), "show").addInterceptors(interceptor()).setAllowedOrigins("*");
} @Bean
public WebSocketHandler handler(){
return new Hanlder();
} @Bean
public HandshakeInterceptor interceptor() {
return new HandshakeInterceptor();
} }
registry.addHandler第一个参数是处理器,自己可以写,第二个参数是前后台建立链接的路径,
addInterceptors 添加拦截,再握手之前之后,处理自己的业务
setAllowedOrigins 解决跨域,*代表不限,如果要指定域名则要http或者https开头
/**
* @author wangqq
* @version 创建时间:2018年11月1日 下午3:06:36
* 类说明
*/
public class Hanlder extends TextWebSocketHandler {
private Logger logger = Logger.getLogger(Hanlder.class);
private static final Map<Integer,WebSocketSession> hotels; static{
hotels = new HashMap<Integer, WebSocketSession>();
} @Override
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
// TODO Auto-generated method stub
Integer hotelid = IHelper.toInteger(session.getAttributes().get("hotelid"));
logger.info("-----------------afterConnectionEstablished-----------------");
if(null != hotelid){
logger.info(String.format("酒店连接,id:%s", hotelid));
hotels.put(hotelid, session);
JSONObject json = new JSONObject();
json.put("code","testMessage");
session.sendMessage(new TextMessage(json.toString()));
} //super.afterConnectionEstablished(session);
}
/**
* js调用websocket.send时候,会调用该方法
*/
@Override
protected void handleTextMessage(WebSocketSession session,
TextMessage message) throws Exception {
// TODO Auto-generated method stub
logger.info(String.format("收到酒店(id:%s)发来消息,消息详情:%s", session.getAttributes().get("hotelid"),message.toString()));
super.handleTextMessage(session, message);
//这里可以给用户发消息
logger.info("执行Hanlder---------客户端收到请求");
} @Override
public void afterConnectionClosed(WebSocketSession session,
CloseStatus status) throws Exception {
// TODO Auto-generated method stub
Integer hotelid = IHelper.toInteger(session.getAttributes().get("hotelid"));
logger.info(String.format("用户退出,酒店id:%s", hotelid));
hotels.remove(hotelid);
super.afterConnectionClosed(session, status);
}
/**
* 给单个用户发消息
* @param hotelid
* @param message
* @throws IOException
*/
public void sendMessage(Integer hotelid,TextMessage message) throws Exception{
if(hotels.containsKey(hotelid)){
if(hotels.get(hotelid).isOpen()){
hotels.get(hotelid).sendMessage(message);
}
} }
/**
* 给所有在线用户发消息
* @param message
* @throws IOException
*/
public void sendMessage(TextMessage message) throws Exception{
for(Integer id : hotels.keySet()){
WebSocketSession session = hotels.get(id);
if(session.isOpen()){
session.sendMessage(message);
}
}
}
/**
* 多个在线用户,不同消息
* @param data
* @throws Exception
*/
public void sendMessage(Map<Integer, TextMessage> data) throws Exception{
for(Map.Entry<Integer, TextMessage> entry : data.entrySet()){
Integer hotelid = entry.getKey();
this.sendMessage(hotelid, entry.getValue());
}
}
/**
* 多个用户,同一消息
* @param hotelids
* @param message
* @throws Exception
*/
public void sendMessage(List<Integer> hotelids,TextMessage message) throws Exception{
for(Integer id : hotelids){
this.sendMessage(id, message);
}
}
}
/**
* @author wangqq
* @version 创建时间:2018年11月2日 下午1:42:00
* 类说明
*/
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor { private Logger logger = Logger.getLogger(HandshakeInterceptor.class); @Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
// TODO Auto-generated method stub
logger.info("-----------beforeHandshake---------");
if(request instanceof ServletServerHttpRequest){
ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest)request;
HttpSession session = serverHttpRequest.getServletRequest().getSession();
if(null != session){
logger.info("拦截请求,存入attribute,酒店id:"+session.getAttribute("hotelid"));
if(null!=session.getAttribute("hotelid")){
attributes.put("hotelid", session.getAttribute("hotelid"));
}
}
}
return super.beforeHandshake(request, response, wsHandler, attributes);
} @Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
// TODO Auto-generated method stub
logger.info("-----------afterHandshake--------------");
super.afterHandshake(request, response, wsHandler, ex);
}
}
前端页面(简单的不能再简单,没有考虑浏览器支不支持)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script language="JavaScript" src="jquery/jquery-1.11.3.min.js" charset="UTF-8"></script>
<script type="text/javascript">
var ws =
$(function(){
$.ajaxSettings.async=false;
$.post('<%=basePath%>/show/doSaveSession',{'hotelid':1},function(data){
console.log("执行保存session");//模拟先登录
});
$.ajaxSettings.async=true;
ws = new WebSocket("ws://localhost:7001/show"); ws.onopen = function () {
console.log("建立链接"); }
ws.onclose = function () {
console.log("onclose");
} ws.onmessage = function (msg) {
console.log("----------------");
console.log(msg.data);
}
}); </script> </head> <body>
This is my JSP page. <br> </body>
</html>
执行结果:
前台
后台:
ps:2018-11-19 更新,后来测试一下,不用提前登陆,直接在前端连socket的路径上面加参数,而后在拦截器的
beforeHandshake中就可把连接的用户存入map
Websocket实现前后台通信,demo小测试的更多相关文章
- 通信服务器群集——跨服务器通信Demo(源码)
对于一些基于TCP Socket的大型C/S应用来说,能进行跨服务器通信可能是一个绕不开的功能性需求.出现这种需求的场景类似于下面描述的这种情况. 假设,我们一台TCP应用服务器能同时承载10000人 ...
- 轻量级通信引擎StriveEngine —— C/S通信demo(2) —— 使用二进制协议 (附源码)
在网络上,交互的双方基于TCP或UDP进行通信,通信协议的格式通常分为两类:文本消息.二进制消息. 文本协议相对简单,通常使用一个特殊的标记符作为一个消息的结束. 二进制协议,通常是由消息头(Head ...
- Cad 二次开发关于SelectCrossingPolygon和SelectFence返回结果Status为error的小测试
CAD2008的二次开发,有个很奇怪的现象,只要你选择的点集不在当前视图上SelectCrossingPolygon和SelectFence返回结果Status就会为error,所以要获取正确的结果, ...
- 客户端程序通过TCP通信传送"小文件"到服务器
客户端程序通过TCP通信传送"小文件"到服务器 [c#源码分享]客户端程序通过TCP通信传送"小文件"到服务器 源码 (不包含通信框架源码,通信框架源码请另行 ...
- VC++ 6.0 C8051F340 USB PC侧通信 Demo
// HelloWorld.cpp : Defines the entry point for the console application. // /*********************** ...
- JAVASE02-Unit011: TCP通信(小程序)
TCP通信(小程序) server端: package chat; import java.io.BufferedReader; import java.io.IOException; import ...
- 基于NIOS II的双端口CAN通信回环测试
基于NIOS II的双端口CAN通信回环测试 小梅哥编写,未经授权,严禁用于任何商业用途 说明:本稿件为初稿,如果大家在使用的过程中有什么疑问或者补充,或者需要本文中所述工程源文件,欢迎以邮件形式发送 ...
- python 程序小测试
python 程序小测试 对之前写的程序做简单的小测试 ... # -*- encoding:utf-8 -*- ''' 对所写程序做简单的测试 @author: bpf ''' def GameOv ...
- 一个基于cocos2d-x 3.0和Box2d的demo小程序
p图demo小应用.想怎么p就怎么p 本文參考于http://blog.csdn.net/xiaominghimi/article/details/6776096和http://www.cnblogs ...
随机推荐
- ES6 数组去重 方法用了filter或者 indexOf Array.from
- drf07 过滤 排序 分页 异常处理 自动生成接口文档
4. 过滤Filtering 对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持. pip install django-filter 在配置文件sett ...
- / Vijos / 题库 /1250 / 最勇敢的机器人
/ Vijos / 题库 /1250 / 最勇敢的机器人 借鉴博客:http://www.cnblogs.com/chty/p/5830516.html 背景 Wind设计了很多机器人.但是它们都认为 ...
- SprinMVC接收参数乱码解决篇
1.Spring 默认的字符编码格式为iso-8859-1,为此Spring专门提供了字符过滤器org.springframework.web.filter.CharacterEncodingFilt ...
- 洛谷 1486 郁闷的出纳员【Treap】
[题意概述] 要求维护一个序列支持以下操作: 1,插入元素x: 2,把序列的所有元素加上x: 3,把序列的所有元素减去x,同时低于一个给定的下限的元素马上被删除: 4,询问序列中第k大的元素. [题解 ...
- 3.3.4 lambda 表达式
lambda表达式常用来声明匿名函数,即没有函数名字的临时使用的小函数,例如第2章中列表对象的sort()方法以及内置函数sorted()中key参数.lambda表达式只可以包含一个表达式,不允许包 ...
- hdu2004 成绩转换【C++】
成绩转换 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- 【郑轻邀请赛 F】 Tmk吃汤饭
[题目链接]:https://acm.zzuli.edu.cn/zzuliacm/problem.php?id=2132 [题意] [题解] 很容易想到用队列来模拟; 这个队列维护的是正在煮的4个人煮 ...
- ReportNG 替换testng获得测试报告
1.导入reportng相关jar包
- toj 1421
题意:假如存在矩阵A,A[i][0] + A[i][1] + ...... + A[i][n - 1] == SR[i],A[0][j] + A[1][j] + ...... + A[n - 1][j ...