新需求大概如下:用户登录系统,登录成功之后建立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. C# 获得固定年月日

    /// <summary> /// 获得固定年月日,时和分不固定 : 2019-01-01 00:00:00 /// </summary> /// <returns> ...

  2. linux虚拟主机的三种方法

    虚拟主机虚拟主机是将一台(或者一组)服务器的资源(系统资源.网络带宽.存储空间等)按照一定的比例分割成若干相对独立的“小主机”的技术.每一台这样的“小主机”在功能上都可以实现WWW.FTP.Mail等 ...

  3. B.4 集

    在.NET 3.5之前,框架中根本没有公开集(set)集合.如果要在.NET 2.0中表示集,通常会 使用 Dictionary<,> ,用集的项作为键,用假数据作为值..NET3.5的 ...

  4. c++ list双向链表管理对象

    #cat list.cc #include <cstdlib> #include <iostream> #include <stdio.h> using names ...

  5. Shell脚本备份文件

    使用crontab 定时备份文件 1. 编辑crontab规则 2. 编写shell脚本 cp -R "/data/www/code" "/home/backup/cod ...

  6. iOS学习笔记18-CoreData你懂的

    一.CoreData介绍 CoreData是iOS5之后新出来的的一个框架, 是对SQLite进行一层封装升级后的一种数据持久化方式. 它提供了对象<-->关系映射的功能,即能够将OC对象 ...

  7. [tsA1491][2013中国国家集训队第二次作业]家族[并查集]

    m方枚举,并查集O(1)维护,傻逼题,,被自己吓死搞成神题了... #include <bits/stdc++.h> using namespace std; struct tri { i ...

  8. [Poj2112][USACO2003 US OPEN] Optimal Milking [网络流,最大流][Dinic+当前弧优化]

    题意:有K个挤奶机编号1~K,有C只奶牛编号(K+1)~(C+K),每个挤奶机之多能挤M头牛,现在让奶牛走到挤奶机处,求奶牛所走的最长的一条边至少是多少. 题解:从起点向挤奶机连边,容量为M,从挤奶机 ...

  9. 【线段树I:母题】hdu 1166 敌兵布阵

    [线段树I:母题]hdu 1166 敌兵布阵 题目链接:hdu 1166 敌兵布阵 题目大意 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又開始忙乎了.A国在海 ...

  10. Kotlin和Java名称的由来

    Kotlin和Java名称的由来 学习了:http://blog.jobbole.com/111249/ JetBrains由战斗民族开发: Java来源于印尼群岛中的Java岛: Kotlin来源于 ...