websocket

  • 1. 概述
  • 2. websocket的用法
  • 3. js代码实现
  • 4. 服务器端代码实现
maven下载地址:

https://mvnrepository.com/artifact/org.java-websocket/Java-WebSocket

1. 概述

  • 什么是websocket
 - WebSocket是一种网络传输协议,
可在单个TCP连接上进行全双工通信,位于OSI模型的应用层。- WebSocket使得客户端和服务器之间的数据交换变得更加简单,
允许服务端主动向客户端推送数据。- 在WebSocket API中,浏览器和服务器只需要完成一次握手,
两者之间就可以创建持久性的连接,并进行双向数据传输。
  • 简介
WebSocket:
建立一次连接即可
连接断开 不会自动重连(心跳机制)
双向发送数据
WebSocket实现比较复杂(使用jar包)
  • sse与websocket的优点
SSE 使用 HTTP 协议,现有的服务器软件都支持。WebSocket 是一个独立协议。
SSE 属于轻量级,使用简单;WebSocket 协议相对复杂。
SSE 默认支持服务器断线重连,WebSocket 需要自己实现。
SSE 一般只用来传送文本,二进制数据需要编码后传送,WebSocket 默认支持传送二进制数据。
SSE 支持自定义发送的消息类型
  • sse与websocket的区别
SSE 与 WebSocket 作用相似,
都是建立浏览器与服务器之间的通信渠道,
然后服务器向浏览器推送信息。总体来说,WebSocket 更强大和灵活。
因为它是全双工通道,可以双向通信;
SSE 是单向通道,只能服务器向浏览器发送,因为流信息本质上就是下载。
如果浏览器向服务器发送信息,就变成了另一次 HTTP 请求

2. websocket的用法

1.启动webSocket服务
2.使用js发送数据 (使用了心跳机制保持连接)
3.webSocket服务收到消息将消息发送给指定webSocket

3. js代码实现

  • js实现(假如现在有一个叫jack的用户连接服务器)
/*** jack 连接服务器websocket js文件*/var websocket = '';
var ajaxPageNum = 1;
var last_health;
var health_timeout = 10;
var tDates = [], tData = [];
var rightIndex;if (window.WebSocket) {// 创建websocket连接  当前连接协议 ip 端口websocket = new WebSocket(encodeURI('ws://' + document.domain + ':8888'));websocket.onopen = function() {console.log('已连接');// 作为标识告诉服务器websocket.send("onlinejack");// 心跳机制 每分钟连接服务器heartbeat_timer = setInterval(function() {keepalive(websocket)}, 60000);};websocket.onerror = function() {console.log('连接发生错误');};websocket.onclose = function() {console.log('已经断开连接');initWs();};// 消息接收 接收到服务器websocket发来的消息websocket.onmessage = function(message) {console.log(message)console.log(message.data)var jsonMsg = JSON.parse(message.data);console.log(jsonMsg);// 业务代码};
} else {alert("该浏览器不支持提醒。<br/>建议使用高版本的浏览器,<br/>如 IE10、火狐 、谷歌  、搜狗等");
}// 上面的代码封装
var initWs = function() {if (window.WebSocket) {websocket = new WebSocket(encodeURI('ws://' + document.domain + ':8888'));websocket.onopen = function() {console.log('已连接');websocket.send("onlinejack");heartbeat_timer = setInterval(function() {keepalive(websocket)}, 60000);};websocket.onerror = function() {console.log('连接发生错误');};websocket.onclose = function() {console.log('已经断开连接');initWs();};// 消息接收websocket.onmessage = function(message) {console.log(message)console.log(message.data)// 业务代码};} else {alert("该浏览器不支持提醒。<br/>建议使用高版本的浏览器,<br/>如 IE10、火狐 、谷歌  、搜狗等");}
}// 心跳包
function keepalive(ws) {var time = new Date();if (last_health != -1 && (time.getTime() - last_health > health_timeout)) {// ws.close();} else {if (ws.bufferedAmount == 0) {ws.send('connect again from jack...');}}
}

4. 服务器端代码实现

  • websocket连接池
package websocket;import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;import org.java_websocket.WebSocket;public class WsPool {private static final Map<WebSocket, String> wsUserMap = new HashMap<WebSocket, String>();/*** 通过websocket连接获取其对应的用户* * 根据连接对象获得连接对象对应的订单号* @param conn* @return*/public static String getUserByWs(WebSocket conn) {return wsUserMap.get(conn);}/*** 根据userName获取WebSocket,这是一个list,此处取第一个* 因为有可能多个websocket对应一个userName(但一般是只有一个,因为在close方法中,我们将失效的websocket连接去除了)* 根据订单号找到对应的连接对象websocket* * @param user*/public static WebSocket getWsByUser(String userName) {Set<WebSocket> keySet = wsUserMap.keySet();synchronized (keySet) {for (WebSocket conn : keySet) {String cuser = wsUserMap.get(conn);if (cuser.equals(userName)) {return conn;}}}return null;}/*** 向连接池中添加连接* * @param inbound*/public static void addUser(String userName, WebSocket conn) {wsUserMap.put(conn, userName); // 添加连接}/*** 获取所有连接池中的用户,因为set是不允许重复的,所以可以得到无重复的user数组* * @return*/public static Collection<String> getOnlineUser() {List<String> setUsers = new ArrayList<String>();Collection<String> setUser = wsUserMap.values();for (String u : setUser) {setUsers.add(u);}return setUsers;}/*** 移除连接池中的连接* * @param inbound*/public static boolean removeUser(WebSocket conn) {if (wsUserMap.containsKey(conn)) {wsUserMap.remove(conn); // 移除连接return true;} else {return false;}}/*** 向特定的用户发送数据* * @param user* @param message*/public static void sendMessageToUser(WebSocket conn, String message) {if (null != conn && null != wsUserMap.get(conn)) {conn.send(message);}}/*** 向所有的用户发送消息* 广播* * @param message*/public static void sendMessageToAll(String message) {Set<WebSocket> keySet = wsUserMap.keySet();synchronized (keySet) {for (WebSocket conn : keySet) {String user = wsUserMap.get(conn);if (user != null) {conn.send(message);}}}}
}
  • websocket服务器 对用户的操作
package websocket;import java.net.InetSocketAddress;import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;public class WsServer extends WebSocketServer {public WsServer(int port) {super(new InetSocketAddress(port));}public WsServer(InetSocketAddress address) {super(address);}@Overridepublic void onOpen(WebSocket conn, ClientHandshake handshake) {// ws连接的时候触发的代码,onOpen中我们不做任何操作}@Overridepublic void onClose(WebSocket conn, int code, String reason, boolean remote) {//断开连接时候触发代码userLeave(conn);System.out.println(reason);}@Overridepublic void onMessage(WebSocket conn, String message) {//客户端发送消息给服务器,自动执行此方法System.out.println(message);//服务器端发送消息给客户端,//conn.send("消息内容");if(null != message &&message.startsWith("online")){userJoin(conn,message);//用户加入}else if(null != message && message.startsWith("offline")){userLeave(conn);}}@Overridepublic void onError(WebSocket conn, Exception ex) {//错误时候触发的代码System.out.println("on error");ex.printStackTrace();}/*** 去除掉失效的websocket链接* @param conn*/private void userLeave(WebSocket conn){WsPool.removeUser(conn);}/*** 将websocket加入用户池* @param conn* @param userName*/private void userJoin(WebSocket conn,String userName){WsPool.addUser(userName, conn);}}
  • 配置websocket启动 8080port(这里使用过滤器)
package filter;import java.io.IOException;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;import org.java_websocket.WebSocketImpl;import websocket.WsServer;public class StartWebSocket implements Filter {@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException {}@Overridepublic void init(FilterConfig arg0) throws ServletException {this.startWebSocketInstantMsg();}/*** 启动websocket 服务*/public void startWebSocketInstantMsg() {System.out.println("开始启动webSocket服务...");WebSocketImpl.DEBUG = false;// 端口WsServer server = new WsServer(8888);server.start();}}
  • 发送消息为demo
// websocket向客户端发送消息
// 根据用户名找到 用户和服务器连接到的websocket对象
WebSocket wsConn = WsPool.getWsByUser("online" + toName);
// 发送单条消息
msg.setMsgDate(new Timestamp(System.currentTimeMillis()));
// System.out.println(wsConn + "\t" + JSON.toJSONString(msg));
WsPool.sendMessageToUser(wsConn, JSON.toJSONString(msg));

websocket使用相关推荐

  1. mqtt+htttp+websocket

    一.介绍 1.参考网址1:WebSocket协议:5分钟从入门到精通 2.参考网址2:WebSocket 教程(阮一峰) 二.应用 1.参考网址1:从 HTTP 到 MQTT:一个移动后端案例概述 2 ...

  2. Java后端WebSocket的Tomcat实现

    转自: http://blog.chenzuhuang.com/archive/28.html http://www.cnblogs.com/xdp-gacl/p/5193279.html 一.Web ...

  3. Java Websocket实例【服务端与客户端实现全双工通讯】

    Java Websocket实例[服务端与客户端实现全双工通讯] 现很多网站为了实现即时通讯,所用的技术都是轮询(polling).轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发 出HTTP ...

  4. 物联网协议对比(HTTP、websocket、XMPP、COAP、MQTT和DDS协议)

    目录 1.HTTP和websocket 2.XMPP 3.COAP 4.MQTT协议 5.DDS 对于物联网,最重要的是在互联网中设备与设备的通讯,现在物联网在internet通信中比较常见的通讯协议 ...

  5. node.js创建WebSocket服务,并使用原生js ES6完成对WebSocket数据交互

    注意,前情提示: 本代码基于<Node.js(nodejs)对本地JSON文件进行增.删.改.查操作(轻车熟路)> 传送门Node.js(nodejs)对本地JSON文件进行增.删.改.查 ...

  6. 使用CEfSharp之旅(7)CEFSharp 拦截 http 请求 websocket 内容

    使用CEfSharp之旅(7)CEFSharp 拦截 http 请求 websocket 内容 原文:使用CEfSharp之旅(7)CEFSharp 拦截 http 请求 websocket 内容 版 ...

  7. 使用Node.js快速搭建WebSocket server

    原文地址:http://my.oschina.net/yushulx/blog/309413 目录[-] 安装 服务端 客户端 参考 安装 ? 1 npm install ws 服务端 server. ...

  8. python java web_Python 与 Java 使用 websocket 通信

    WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信--允许服务器主动发送信息给客户端. Java服务端 import java.io.IO ...

  9. Java项目:在线淘房系统(租房、购房)(java+SpringBoot+Redis+MySQL+Vue+SpringSecurity+JWT+ElasticSearch+WebSocket)

    源码获取:博客首页 "资源" 里下载! 该系统有三个角色,分别是:普通用户.房屋中介.管理员.普通用户的功能:浏览房屋信息.预约看房.和中介聊天.申请成为中介等等.房屋中介的功能: ...

  10. websocket心跳链接代码_WebSocket原理与实践(五)--心跳及重连机制

    在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务器端并没有触发onclose的事件.这样会有:服务器会继续向客户端发送多余的链接,并且这些数据还会丢失.所以就需要 ...

最新文章

  1. 美团实习面试:熟悉红黑树?能不能手写一下?
  2. 诗与远方:无题(五十七)
  3. Spring学习之旅(四):面向切面编程(AOP)
  4. python自动测试g_python自动化测试报告(excel篇)
  5. 每次发工资条,同事都要随意传看,怎么解决这个问题?
  6. JavaSE基础——Map集合、 Collections(集合工具类)
  7. 前端打包混编压缩js代码,如何不重新打包,修改js文件内部配置参数?
  8. java tbase_TBase备份恢复实验
  9. 详解网站WEB日志格式
  10. Windows 上C++ new/detele如何知道内存大小
  11. SVG绘制不同形状的图形
  12. matlab人口增长线性回归拟合_Matlab线性回归(拟合)
  13. 《高效阅读——20分钟读懂一本书》读书总结
  14. 一个迷茫的应届生程序员
  15. 【毕业设计】深度学习人脸表情识别系统 - python
  16. 上帝之眼——GIS技术的决定性作用
  17. STM32H743内部所有SRAM的使用
  18. Scratch3.0——助力新进程序员理解程序(案例九、等差数列2)
  19. 如何低成本挖掘App商店的免费资源
  20. [转载]投资正道vs冯时能30年股票投资16心得

热门文章

  1. 前端学习(1233):组件化开发思想
  2. 前端学习(530):等分布局得间距方案第二种方式
  3. spring学习(22):分层架构
  4. 第四十九期:大牛总结的MySQL锁优化,写得太好了!
  5. android tabhost 多个activity,Android:TabHost中Activity的生命周期问题
  6. oracle新建用户sql局域,oracle 新建数据库,及创建用户,表空间,sqlplus导入导出数据库...
  7. Vue项目 开启gzip
  8. 三次样条插值 cubic spline interpolation
  9. oracle 添加字段
  10. 李超线段树 [Heoi2013]Segment