新需求大概如下:用户登录系统,登录成功之后建立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小测试的更多相关文章

  1. 通信服务器群集——跨服务器通信Demo(源码)

    对于一些基于TCP Socket的大型C/S应用来说,能进行跨服务器通信可能是一个绕不开的功能性需求.出现这种需求的场景类似于下面描述的这种情况. 假设,我们一台TCP应用服务器能同时承载10000人 ...

  2. 轻量级通信引擎StriveEngine —— C/S通信demo(2) —— 使用二进制协议 (附源码)

    在网络上,交互的双方基于TCP或UDP进行通信,通信协议的格式通常分为两类:文本消息.二进制消息. 文本协议相对简单,通常使用一个特殊的标记符作为一个消息的结束. 二进制协议,通常是由消息头(Head ...

  3. Cad 二次开发关于SelectCrossingPolygon和SelectFence返回结果Status为error的小测试

    CAD2008的二次开发,有个很奇怪的现象,只要你选择的点集不在当前视图上SelectCrossingPolygon和SelectFence返回结果Status就会为error,所以要获取正确的结果, ...

  4. 客户端程序通过TCP通信传送"小文件"到服务器

    客户端程序通过TCP通信传送"小文件"到服务器 [c#源码分享]客户端程序通过TCP通信传送"小文件"到服务器 源码  (不包含通信框架源码,通信框架源码请另行 ...

  5. VC++ 6.0 C8051F340 USB PC侧通信 Demo

    // HelloWorld.cpp : Defines the entry point for the console application. // /*********************** ...

  6. JAVASE02-Unit011: TCP通信(小程序)

    TCP通信(小程序) server端: package chat; import java.io.BufferedReader; import java.io.IOException; import ...

  7. 基于NIOS II的双端口CAN通信回环测试

    基于NIOS II的双端口CAN通信回环测试 小梅哥编写,未经授权,严禁用于任何商业用途 说明:本稿件为初稿,如果大家在使用的过程中有什么疑问或者补充,或者需要本文中所述工程源文件,欢迎以邮件形式发送 ...

  8. python 程序小测试

    python 程序小测试 对之前写的程序做简单的小测试 ... # -*- encoding:utf-8 -*- ''' 对所写程序做简单的测试 @author: bpf ''' def GameOv ...

  9. 一个基于cocos2d-x 3.0和Box2d的demo小程序

    p图demo小应用.想怎么p就怎么p 本文參考于http://blog.csdn.net/xiaominghimi/article/details/6776096和http://www.cnblogs ...

随机推荐

  1. Jenkins里jobs和workspace什么区别

    https://segmentfault.com/q/1010000012575095/a-1020000012590560 简单的说,job 中保存的是项目是在 jenkins 上的配置.日志.构建 ...

  2. linux设置crontab定时执行脚本备份mysql

    前言:mysqldump备份数据库命令 mysqldump -u root -psztx@2018 fengliuxiaosan > /dbbackup/fengliuxiaosan.sql## ...

  3. Servlet+JSP(三):第一个Web程序

    Servlet+JSP(三):第一个Web程序在学习了服务器并成功安装后,我们知道当浏览器发送请求给服务器后,服务器会调用并执行对应的逻辑代码进行请求处理.逻辑代 码是由程序员自己编写然后放进服务器进 ...

  4. Django - 一对多跨表操作

    1.views.py 2.host.html 运行结果: 通过外键,来进行多表取值(多表取值包括后台取值及前端获取): 多表获取数据时,可以通过以下几种方式实现: 1.从query  set 中获取某 ...

  5. JavaScript day3(转义符)

    转义符(escape character) 当你定义一个字符串必须要用单引号或双引号来包裹它.那么当你需要在字符串中使用一个: "  或者 ' 时该怎么办呢? 在 JavaScript 中可 ...

  6. Yin and Yang Stones(思路题)

    Problem Description: A mysterious circular arrangement of black stones and white stones has appeared ...

  7. php观察折模式

    <?php class Paper{ private $_observers = array(); public function register($sub){ $this->_obse ...

  8. java堆排序实现

    代码如下: public class HeapSort { public static void heapSort(DataWrap[] data) { System.out.println(&quo ...

  9. 熟悉RHEL7登录界面使用

    Linux操作系统提供了图像界面和字符界面两种操作环境. 图像界面: 1.开启RHEL7后进入到该界面,图中用户是我们创建的本地用户,如果我们要以管理员身份登录则点击Not listed(未列出). ...

  10. Flask - 路由系统

    目录 Flask - 路由系统 @app.route()装饰器中的常用参数 methods : 当前 url 地址,允许访问的请求方式 endpoint:反向url地址,默认为视图函数名(url_fo ...