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 ...
随机推荐
- git怎么克隆远程仓库到本地仓库
参考: https://blog.csdn.net/zhangzeshan/article/details/81564990 不知道为什么输入git的克隆地址就会提示密码错误 ,使用http地址就直接 ...
- Cesium学习笔记(四)Camera
http://blog.csdn.net/HobHunter/article/details/74909641 Cesium 相机控制场景中的视野.操作相机的方法有很多,如旋转,缩放,平移和飞到目的地 ...
- Sping——使用注解创建切面
为讲解例子,我们首先定义一个Performance接口: package aoptest; public interface Performance { public void perform(); ...
- uva1584 Circular Sequence(Uva-1584)
vj:https://vjudge.net/problem/UVA-1584 这个题讲的是一个圆环,圆环上面有一堆字母,找出字典序最小的那一圈 这个题我觉得直接用c语言的strcmp那一套感觉真是用不 ...
- nexus3的安装和使用
参考:https://www.cnblogs.com/2YSP/p/9533506.html http://www.54tianzhisheng.cn/2017/10/14/Nexus3-Maven/ ...
- win10如何进入安全模式的几种方法
首先,说一下安全模式的作用: 安全模式, 用途有很多,常见的作用有以下几点 1. 电脑可能由于安装了某些驱动或者软件,不兼容导致电脑启动不了,可以进入安全模式卸载 2. 电脑中病毒之后,可以进入安全模 ...
- 方便简单的远程控制:putty和WinSCP
记录一下WinSCP和putty的用法. putty:远程cmd窗口,在本机通过命令行操作服务器,并且拿到运行结果.而本机只有连接作用,大大减小了负担. 登陆界面输入ip地址,没有特殊情况,默认选项就 ...
- hadoop balancer
一.balancer是当hdfs集群中一些datanodes的存储要写满了或者有空白的新节点加入集群时,用于均衡hdfs集群磁盘使用量的一个工具.这个工具作为一个应用部署在集群中,可以由集群管理员在一 ...
- JavaSE 学习笔记之多线程(十三)
多线程: 进程:正在进行中的程序.其实进程就是一个应用程序运行时的内存分配空间. 线程:其实就是进程中一个程序执行控制单元,一条执行路径.进程负责的是应用程序的空间的标示.线程负责的是应用程序的执行顺 ...
- FOJ2250 不可能弹幕结界
Problem 2250 不可能弹幕结界 Time Limit: 1000 mSec Memory Limit : 65536 KB Problem Description 咲夜需要穿过一片弹幕 ...