websocket握手过程在实现过程中存在哪些阻拦

SuperWebSocket在WebService中的应用
最开始使用是寄托在IIS中,发布之后测试时半个小时就会断开,所以改为WindowsService
1. 新建Windows服务项目【TestWindowsService】,重命名Service1为MyWebSocketService
2. 打开MyWebSocketService设计视图,右键,添加安装程序,自动添加ProjectInstaller.cs。
打开设计视图,选中ServiceInstaller1,右键修改属性:
ServiceName(服务名):这里改为我们刚重命名的MyWebSocketService
StartType(启动方式):改为自动启动Automatic
DelayedAutoStart(延迟加载)
选中serviceProcessInstaller1,右键修改属性:
Account(账户类型):这里改为LocalSystem
3. 添加安装和卸载文件。注意添加文件请使用ANSI编码。推荐使用EditPlus等工具新建文件,然后通过项目添加现有项。
注意替换TestWindowsService.exe和MyWebSocketService。右键属性,设置复制到输出目录。
Install.bat:
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe TestWindowsService.exe
sc config MyWebSocketService start= auto
Net Start MyWebSocketService
Uninstall.bat
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u TestWindowsService.exe
4. 添加App.config,配置IP和Port。
IP地址为本地连接地址,端口号自定义。确保端口号不被占用。
5. 修改MyWebSocketService服务代码。
推荐手动加载dll,通过Nuget加载时,添加依赖的Log4net版本与SuperWebSocket中调用的Log4net版本存在冲突。log4net版本为1.2.11.0
项目右键,管理Nuget程序包,搜索SuperWebSocket,注意作者为Kerry Jiang。
WebSocketS
protected override void OnStart(string[] args)
var ip = ConfigurationManager.AppSettings["APWebSocketIP"];
var port = ConfigurationManager.AppSettings["APWebSocketPort"];
6.添加log4net配置文件。查看日志。
由于SuperWebSocket已经有日志功能,只需要添加配置文件,即可查看日志。
&?xml version="1.0" encoding="utf-8" ?&
在html中使用WebSocket
1.首先考虑浏览器兼容问题。一些低版本浏览器不支持。
2.创建websocket对象,设置ip和端口。
var url = "ws://192.168.1.199:8200";
$("#btnConnection").click(function () {
if ("WebSocket" in window) {
ws = new WebSocket(url);
else if ("MozWebSocket" in window) {
ws = new MozWebSocket(url);
alert("浏览器版本过低,请升级您的浏览器。\r\n浏览器要求:IE10+/Chrome14+/FireFox7+/Opera11+");
这里模拟一个学生A和考场的交互。
首先连接考场。
接着连接考生。
考场发送消息,通知学生开始考试。
学生接到消息,开始答题。
考试收到考生开始答题消息。
1.首先拷贝TestWebService中的bin\Debug|Release中生成的文件到服务器。通过开始运行,查看服务器的本地链接地址(192开头)。修改App.config中的IP和端口号。
2.双击Install.bat文件,等待安装服务。
3.修改html中的WebSocket对象的ip和端口号。
通过Install.bat无法启动时,可以查看本地日志文件和控制面板的事件管理器,定位详细错误
原文链接:/articles/jqa6Zb
阅读(...) 评论()了解 WebSocket 的功能
我的图书馆
了解 WebSocket 的功能
当今的万维网并未设计成一个实时媒介。&当通过诸如 SignalR 和 Comet 之类的临时库有效实现 Web 应用程序时,Web 应用程序通过传统轮询解决方案(通过 AJAX 实现,或者也可能是通过长轮询请求实现)给人以连续的感观印象。&对于大部分应用程序的需求,轮询是一个不错的解决方案,即便它可能存在客户端到服务器和服务器到客户端的延迟。&本文将探讨一种新的替代方法,称为 WebSocket。随着 Web 和移动应用程序与社交媒体之间的集成程度越来越高,人们能够容忍的客户端/服务器交互中的延迟越来越低。&当您更新 Facebook 状态时,您希望该信息能立即被您的好友看到。&同样,当有人喜欢您发布的某个帖子时,您希望能够立即获得相应的通知。&今天,所有这些功能都是切实存在的,这也正是 Facebook 在世界范围内如此热门,以及社交网络现象遍地开花的原因之一。&所以,最终结果就是迫切需要开发人员开发出能够通过 Web 实现实时通信的解决方案和工具。在 Web 客户端和服务器之间实现零滞后连接不仅仅需要 HTTP 协议。&这正是 WebSocket 协议所能提供的。当前存在针对 WebSocket 协议的互联网工程任务组标准;您可以在&&上了解此标准的相关信息。&实现该协议的标准 API 已由万维网联盟 (W3C) 正式确立,以便浏览器支持该协议(请参见)。&规范处于“候选推荐”状态。WebSocket 协议新的 WebSocket 协议旨在解决 HTTP 协议的结构限制,该限制使得浏览器中托管的 Web 应用程序无法通过持久连接高效地与服务器保持连接。&WebSocket 协议允许通过单一 TCP 套接字在 Web 应用程序和 Web 服务器之间实现双向通信。&换句话说,该协议使得浏览器中托管的 Web 应用程序可以一直与 Web 端点保持连接,同时还能将成本(例如服务器的压力、内存和资源消耗)降到最低。&实际效果是数据和通知在浏览器和 Web 服务器之间能够无延迟地发送和接收,并且无需安排额外的请求。&不容置疑,WebSocket 协议为开发人员打开了一个全新的充满无限可能的世界,让基于轮询的小把戏和框架都成为了历史。&其实并不完全是这样。当今的 WebSocket 应用WebSocket 协议的浏览器支持将会很快得到改善,但是只有最新版本的浏览器支持 WebSocket。&不经常升级浏览器的用户(或者因严格的公司策略而不允许升级的用户)将会落伍。这意味着开发人员不能简单地放弃基于 AJAX 轮询的代码或长轮询解决方案。&在这方面,请关注 SignalR(即将推出的 Microsoft 框架,用于在浏览器和 Web 服务器之间实现零延迟消息传递),它在抽象化持久性连接、支持时自动切换到 WebSocket,以及在任何其他情况下使用长轮询方面,效果非常不错。&我在近期的专栏中已经介绍了 SignalR,如果您还未试用过 SignalR,我再次邀请您尽早尝试一下。&SignalR 毋庸置疑是所有开发人员和 Web 应用程序首选的库和工具。当今有谁支持 WebSocket?图 1&简单地列出了目前大多数热门浏览器提供的 WebSocket 支持。图 1 WebSocket 的浏览器支持浏览器WebSocket 支持Internet ExplorerInternet Explorer 10 将支持 WebSocket。&使用 JavaScript 和 HTML5 编写的 Metro 应用程序也将支持 WebSocket。Firefox从 2011 年年中发布的第 6 版浏览器开始支持 WebSocket。&在很早以前的第 4 版中曾提供过一些支持,但是在第 5 版时却弃用了这些支持。Chrome从 2011 年 9 月发布的第 14 版开始支持 WebSocket。Opera在第 11 版中删除了对 WebSocket 的支持。Safari支持早期版本的 WebSocket 协议。除 Firefox 外,您可以使用编程的方式通过查看 window.WebSocket 对象来了解 WebSocket 支持。&对于 Firefox,您当前应该查看 MozWebSocket 对象。&您应该注意到,大多数 HTML5 相关的功能都可以在浏览器中通过诸如 Modernizr () 的专用库的方式进行查看。&特别是,如果您将 Modernizr 库链接到页面,则下面是您需要编写的 JavaScript 代码:&&&&&&&&&&&&(Modernizr.websockets){&&...&&&&&&&&&&}&&&&&&&&如果您想要开始使用 WebSocket 实现,那么 Modernizr 可能是当下一个非常不错的选择,因为它向您提供填充代码,在当前浏览器不支持指定功能时会自动插入该代码。因此,WebSocket 功能魅力无穷,但当下供应商的支持尚不统一。&然而 Microsoft 在即将推出的 Internet Explorer 10,以及 IIS、ASP.NET、Windows Communication Foundation (WCF) 和 Windows Runtime (WinRT) 中广泛支持 WebSocket。&请注意,尚不存在官方的标准 API,因此早期支持会引起业内极大的关注。&现如今您最多只能通过某个抽象层使用 WebSocket。&如果您想更接近事物本质并编写您自己的用于打开和关闭 WebSocket 的代码,则可以选择 Modernizr。&如果您要寻找一种框架以便以持久方式透明地连接浏览器和 Web 端点,而无需知道太多的底层详细信息,那么 SignalR 是更好的选择。WebSocket 协议简介双向通信的 WebSocket 协议要求客户端和服务器应用程序都了解协议详细信息。&这意味着您需要调用符合 WebSocket 的端点的符合 WebSocket 的网页。WebSocket 交互从一次握手开始,在这次握手中,双方(浏览器和服务器)互相确认它们想通过持久性连接通信的意图。&接下来,在两个方向上通过 TCP 发送大量消息包。&图 2&概述了 WebSocket 协议的工作方式。&图 2 WebSocket 协议架构请注意,除了图 2&中显示的内容以外,当连接关闭时,两个端点会交换一个关闭帧以干净利落地关闭连接。初次握手包含一个客户端发送给 Web 服务器的普通 HTTP 请求。&请求是配置为升级请求的 HTTP GET:
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
在 HTTP 中,具有 Upgrade 标头的客户端请求表示客户端想请求服务器切换到其他协议。&通过 WebSocket 协议,发往服务器的升级请求包含一个唯一的密钥,服务器会将其破坏并返回,作为它接受升级请求的证据。&这是表示服务器理解 WebSocket 协议的实际证明。&下面是握手请求的示例响应:
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
成功的状态代码始终是 101,而任何其他状态代码将解释为拒绝升级到 WebSocket 协议。&服务器将收到的密钥与固定的 GUID 字符串连接,并计算生成的字符串的哈希值。&然后将哈希值编码为 Base64 并通过 Sec-WebSocket-Accept 标头将其返回给客户端。客户端还可以发送其他标头(例如 Sec-WebSocket--Protocol)以表示它愿意采用哪些子协议。&子协议是在基本 WebSocket 协议基础之上构建的应用程序级别协议。&如果服务器理解建议的某些子协议,那么它将选择一个子协议并通过同一标头将子协议名称发送回客户端。握手之后,客户端和服务器可以通过 WebSocket 协议自由发送消息。&负载从一个表示操作正在执行的操作码开始。&这些操作码的其中之一(具体说就是 0x8)表示关闭会话的请求。&请注意,WebSocket 消息异步发送,所以发送请求不一定会立即收到响应,与在 HTTP 中一样。&使用 WebSocket 协议,您最好从客户端和服务器相互发送的常规消息方面进行思考,忘记传统的 HTTP 请求/响应模式。WebSocket 端点常用的 URL 采用以下形式:&&&&&&&&&&&&myWebSocket&=&&&&new&WebSocket("ws://www.websocket.org");&&&&&&&&如果您想要保持安全套接字连接,则可以使用 wss 协议前缀(当存在中间媒介时,安全连接通常会更成功)。&最后,WebSocket 协议承认并解决跨域通信的问题。&WebSocket 客户端通常(但不总是)允许将请求发送至位于任何域的端点。&但是,接受还是拒绝握手请求的决定权在 WebSocket 服务器。WebSocket API 简介正如之前所提到的,W3C 当前正在标准化用于 WebSocket 协议的 API,各种浏览器也正在争取符合推出的各种草案的要求。&您应该了解,今天能够使用的任何代码可能无法在所有的浏览器中使用,更重要的是,当同一浏览器的新版本问世时,甚至无法保证这些代码能够在该同一浏览器中使用。&在任何情况下,只要您具有有效的 WebSocket 代码,您基本上就完成得差不多了,因为将来可能需要做出的任何更改可能都只是微小改动。如果您想要试用 WebSocket 协议,可以使用支持该协议的浏览器访问 websocket.org。&例如,您可以使用 Internet Explorer 10 的预览版或 Google Chrome 的最新版本。&图 3&显示 Fiddler 跟踪的握手过程。&图 3 浏览器和服务器之间的实际握手过程实际上,当前版本的 Fiddler(版本 2.3.x)仅捕获 HTTP 流量。&不过,处理 WebSocket 流量的 Fiddler 新版本当前处于 Beta 阶段。WebSocket API 相当简单。&在浏览器端,您需要创建 WebSocket 浏览器类的实例。&该类公开您希望具有其相应处理程序的大量相关事件:&&&&&&&&&&&&wsUri&=&"&ws://echo.websocket.org/";websocket&=&new&WebSocket(wsUri);websocket.onopen&=&function(evt)&{&onOpen(evt)&};websocket.onmessage&=&function(evt)&{&onMessage(evt)&};websocket.onclose&=&function(evt)&{&onClose(evt)&};websocket.onerror&=&function(evt)&{&onError(evt)&};&&&&&&&&建立连接时触发 onopen 事件。&每当客户端收到来自服务器的消息时都会触发 onmessage 事件。&关闭连接时触发 onclose。&最后,发生错误时触发 onerror。要向服务器发送消息,您只需要调用 send 方法即可,如下所示:&&&&&&&&&&&&message&=&"Cutting&Edge&test:&"&+&&new&Date().toString();websocket.send(message);&&&&&&&&图 4&显示一个示例页面,该页面是根据 websocket.org 网站上找到的回显示例改写的。&在该示例中,服务器只是将收到的消息回显给客户端。&图 4 WebSocket 协议的实际应用如果您对 Internet Explorer 10 的 WebSocket 编程感兴趣,请参见&。WebSocket 的服务器端在本文中,我主要介绍了 WebSocket 协议客户端方面的事项。&有一点应该清楚,要使用 WebSocket 客户端,您需要能够理解请求并能适当回复的符合 WebSocket 标准的相应服务器。&构建 WebSocket 服务器的框架已开始出现。&例如,您可以尝试用于 Java 和 Node.js 的 Socket.IO (socket.io)。&如果您要寻找某些 Microsoft .NET Framework 材料,不妨查看一下 The Code Project 中的“Web 套接字服务器”,网址为。&此外,IIS、ASP.NET 和 WCF 中提供面向 WebSocket 的 Microsoft 服务器支持。&有关详细信息,您可以观看第 9 频道的视频“使用 IIS、ASP.NET 和 WCF 通过 WebSocket 构建实时的 Web 应用程序”()。Sliced Bread、Hot Water 和 WebSocket正如很多人所说的,WebSocket 是继切片面包和热水之后最有用的发明。&在了解 WebSocket 之后,您就会禁不住想知道如果没有这些发明创造,软件世界该如何繁荣昌盛。&WebSocket 对于许多应用程序都很有用,虽然不是对所有的应用程序都有用。&对于即时消息传递至关重要的任何应用程序,您都可以认真考虑构建 WebSocket 服务器和大量客户端,例如 Web、移动设备甚至是台式机。&游戏和现场播放应用程序是能够从 WebSocket 协议获得极大利益的另外两个行业领域。&是的,WebSocket 的确是继热水之后最棒的发明!
TA的最新馆藏
喜欢该文的人也喜欢spring配置websocket并实现群发/单独发送消息 - CSDN博客
spring配置websocket并实现群发/单独发送消息
spring框架中自带了websocket的jar包,利用它可以实现与H5中WebSocket的对接,甚至websocket还可以通过依赖注入与http请求一同工作,详细配置实现过程如下
文件目录结构如下,主要是controller和websocket文件夹
1.配置自动扫描加载:
base-package="com.xiaoxiaohei.ssm.websocket,com.xiaoxiaohei.ssm.controller"&&
validator="validator"&&
2.创建一个WebSocket配置类(这里也可以用配置文件来实现其实),实现接口来配置Websocket请求的路径和拦截器。
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myHandler(), "/myHandler").addInterceptors(new WebSocketInterceptor());
public WebSocketHandler myHandler() {
return new MyHandler();
3.拦截器主要是用于用户登录标识(userId)的记录,便于后面获取指定用户的会话标识并向指定用户发送消息,在下面的拦截器中,我在session中获取会话标识(这个标识是在登录时setAttribute进去的,后面代码会说到),你也可以通过H5在new WebSocket(url)中,在url传入标识参数,然后通过serverHttpRequest.getServletRequest().getParameterMap()来获取标识信息。
public class WebSocketInterceptor implements HandshakeInterceptor {
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Map&String, Object& map) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest)
HttpSession session = serverHttpRequest.getServletRequest().getSession();
if (session != null) {
map.put("userId", session.getAttribute("userId"));
return true;
public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
4.实现Websocket建立连接、发送消息、断开连接等时候的处理类。
在这个类中,主要的处理流程如下:
a.在afterConnectionEstablished连接建立成功之后,记录用户的连接标识,便于后面发信息,这里我是记录将id记录在Map集合中。
b.在handleTextMessage中可以对H5 Websocket的send方法进行处理
c.sendMessageToUser向指定用户发送消息,传入用户标识和消息体
d.sendMessageToAllUsers向左右用户广播消息,只需要传入消息体
e.handleTransportError连接出错处理,主要是关闭出错会话的连接,和删除在Map集合中的记录
f.afterConnectionClosed连接已关闭,移除在Map集合中的记录。
g.getClientId我自己封装的一个方法,方便获取用户标识
public class MyHandler extends TextWebSocketHandler {
private static final Map&Integer, WebSocketSession&
private static final String CLIENT_ID = "userId";
users = new HashMap&&();
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("成功建立连接");
Integer userId = getClientId(session);
System.out.println(userId);
if (userId != null) {
users.put(userId, session);
session.sendMessage(new TextMessage("成功建立socket连接"));
System.out.println(userId);
System.out.println(session);
public void handleTextMessage(WebSocketSession session, TextMessage message) {
System.out.println(message.getPayload());
WebSocketMessage message1 = new TextMessage("server:"+message);
session.sendMessage(message1);
} catch (IOException e) {
e.printStackTrace();
* 发送信息给指定用户
* clientId
public boolean sendMessageToUser(Integer clientId, TextMessage message) {
if (users.get(clientId) == null) return false;
WebSocketSession session = users.get(clientId);
System.out.println("sendMessage:" + session);
if (!session.isOpen()) return false;
session.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
return false;
return true;
* 广播信息
public boolean sendMessageToAllUsers(TextMessage message) {
boolean allSendSuccess = true;
Set&Integer& clientIds = users.keySet();
WebSocketSession session = null;
for (Integer clientId : clientIds) {
session = users.get(clientId);
if (session.isOpen()) {
session.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
allSendSuccess = false;
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
if (session.isOpen()) {
session.close();
System.out.println("连接出错");
users.remove(getClientId(session));
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("连接已关闭:" + status);
users.remove(getClientId(session));
public boolean supportsPartialMessages() {
return false;
* 获取用户标识
private Integer getClientId(WebSocketSession session) {
Integer clientId = (Integer) session.getAttributes().get(CLIENT_ID);
return clientId;
} catch (Exception e) {
return null;
封装完成后,下面是具体的使用流程:
1.可以建立一个controller用于用户登录,发送消息等(此处需要发送消息,只需要用依赖注入即可)
@Controller
public class SocketController {
@Autowired
@RequestMapping("/login/{userId}")
public @ResponseBody String login(HttpSession session, @PathVariable("userId") Integer userId) {
System.out.println("登录接口,userId="+userId);
session.setAttribute("userId", userId);
System.out.println(session.getAttribute("userId"));
return "success";
@RequestMapping("/message")
public @ResponseBody String sendMessage() {
boolean hasSend = handler.sendMessageToUser(4, new TextMessage("发送一条小xi"));
System.out.println(hasSend);
return "message";
2.具体的html代码:
type="text/javascript"&
$(function() {
console.log("abc");
$.ajax({url:"http://localhost:8080/login/4",success:function(result){
console.log(result);
var ws = new WebSocket("ws://localhost:8080/myHandler")
ws.onopen = function () {
console.log("onpen");
ws.send("{}");
ws.onclose = function () {
console.log("onclose");
ws.onmessage = function (msg) {
console.log(msg.data);
本文已收录于以下专栏:
相关文章推荐
纠结了两天的
折腾了将近一天,终于搭建好websocket服务,中间遇到不少的坑,现在记录一下,也供他们参考少走弯路。
开发环境:4.2.5.RELEASE
Spring Websocket API
1.spring 4.0及以上增加了WebSocket的支持(这里使用4.3.8.RELEASE)
2.spring 支持STOMP协议的WebSock...
WebSocker是一个保持web客户端与服务器长链接的技术。这样在两者通信过程中如果服务器有消息发送给客户端,就无需等待web客户端发送一个请求了(HTTP协议是请求相应式,如果没有Web客户端的请...
最近项目上要做扫码登录,所以研究了一下Spring WebSocket。网上找了很多资料 springmvc(18)使用WebSocket 和 STOMP 实现消息功能、spring
websock...
千言万语不如代码简洁直接,这里直接贴代码,
实现的功能[1]收到http请求后,把请求的内容群发到WebSocket客户端。[2]返回jsp视图。[3]log4j支持。[4]返回json字符串。...
Websocket是HTML5的一项新技术,可以让服务端和客户端进行实时的通信,主要的使用场景有: 实时的聊天系统,对实时性要求比较高的游戏,或者金融行业对股票市场数据的及时获取等。在Spring3的...
1.分析了传统的消息轮回与Websocket的消息推送不同点。
2.对支持Websocket的客户端和服务端容器做了总结。
3.给出了客户端js创建Websocket连接的Demo,服务端实现方式分别...
他的最新文章
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)用户名:secondriver
文章数:227
评论数:206
访问量:368867
注册日期:
阅读量:1297
阅读量:3317
阅读量:588292
阅读量:474861
51CTO推荐博文
&& 文中案例在apache-tomcat-8.0.15和jdk1.8.0_25环境下开发,运行。不过标题上是Java7,并不造成影响,代码中没有涉及任何与jdk1.8.x相关的代码。另外之所以要讲清软件版本,一是为了保证案例能够有个明确的实现背景,二是websocket实现tomcat7.x与tomcat8.x有很大差异。&& & 在JavaEE规范集中我们这里主要看Java API for WebSocket(JSR 356)。Websocket-api提供了Java实现Websocket的接口,其中最重要的几个类和注解如下图:& 上图解释:1.最上面4个注解OnClose,OnError, OnOpen, OnMessage用来标注一个POJO用来处理WebSocket请求的方法;2.Endpoint和EndpointConfig分别定义了端点和端点相关配置的接口方法;3.ClientEndpoint和ServerEndpoint分别定义了客户端和服务器端端点的接口方法;4.Decoder和Encoder分别是解码和编码的接口方法定义;5.Session是与Endpoint相关的WebSocket Session接口方法定义。另外还有其它接口,这里作为初步了解Java websocket api仅列出最有必要的一些。&& Tomcat8.x提供了JavaEE7的标准实现,其中WebSocket 1.1规范给予实现。在使用其开发的依赖环境是Tomcat8.x JDK7。Tomcat8.x提供了服务器端的实现,客户端实现需要借助其他实现如java_websocket。&& Tomcat8.x对WebSocket实现感觉很明朗化了,既然API中定义了WebSocket相关的注解和Session那么Tomcat8.x实现中自然会有相应的处理和实现,下图是简单的关系描述。 上图解释:tomcat的WsSession类实现了Java WebSocket API中的Session接口PojoEndpointBase以及其子类处理与Endpoint相关的类或注解EndpointConfig,Endpoint都与Session的实现类之间存在依赖关系&& 通过了解Java Websocket API和Tomcat8.x对其的实现,认为使用Java WebSocket需要熟悉其中关键类或接口如:Endpoint,EndpointConfig,Client和Server,Encoder和Decoder,Session,MessageHandler。&& 上面大致介绍了Tomcat8.x对Java Websocket的实现,有关WebSocket规范的了解信息可以参考:&&&&& RFC6455:&&& WebSocket服务器端实现:&& 下面是通过代码示例来展示基于WebSocket的实时聊天1.服务器端实现&package&t8j8.
import&java.io.IOE
import&java.util.S
import&java.util.concurrent.CopyOnWriteArrayS
import&javax.websocket.OnC
import&javax.websocket.OnE
import&javax.websocket.OnM
import&javax.websocket.OnO
import&javax.websocket.S
import&javax.websocket.server.PathP
import&javax.websocket.server.ServerE
@ServerEndpoint(value&=&"/ws/chat/{nickName}")
public&class&Chat&{
&&&&&*&连接对象集合
&&&&private&static&final&Set&Chat&&connections&=&new&CopyOnWriteArraySet&Chat&();
&&&&private&String&nickN
&&&&&*&WebSocket&Session
&&&&private&Session&
&&&&public&Chat()&{
&&&&&*&打开连接
&&&&&*&@param&session
&&&&&*&@param&nickName
&&&&@OnOpen
&&&&public&void&onOpen(Session&session,
&&&&&&&&&&&&@PathParam(value&=&"nickName")&String&nickName)&{
&&&&&&&&this.session&=&
&&&&&&&&this.nickName&=&nickN
&&&&&&&&connections.add(this);
&&&&&&&&String&message&=&String.format("System&&%s&%s",&this.nickName,
&&&&&&&&&&&&&&&&"&has&joined.");
&&&&&&&&Chat.broadCast(message);
&&&&&*&关闭连接
&&&&@OnClose
&&&&public&void&onClose()&{
&&&&&&&&connections.remove(this);
&&&&&&&&String&message&=&String.format("System&&%s,&%s",&this.nickName,
&&&&&&&&&&&&&&&&"&has&disconnection.");
&&&&&&&&Chat.broadCast(message);
&&&&&*&接收信息
&&&&&*&@param&message
&&&&&*&@param&nickName
&&&&@OnMessage
&&&&public&void&onMessage(String&message,
&&&&&&&&&&&&@PathParam(value&=&"nickName")&String&nickName)&{
&&&&&&&&Chat.broadCast(nickName&+&"&"&+&message);
&&&&&*&错误信息响应
&&&&&*&@param&throwable
&&&&@OnError
&&&&public&void&onError(Throwable&throwable)&{
&&&&&&&&System.out.println(throwable.getMessage());
&&&&&*&发送或广播信息
&&&&&*&@param&message
&&&&private&static&void&broadCast(String&message)&{
&&&&&&&&for&(Chat&chat&:&connections)&{
&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&synchronized&(chat)&{
&&&&&&&&&&&&&&&&&&&&chat.session.getBasicRemote().sendText(message);
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}&catch&(IOException&e)&{
&&&&&&&&&&&&&&&&connections.remove(chat);
&&&&&&&&&&&&&&&&try&{
&&&&&&&&&&&&&&&&&&&&chat.session.close();
&&&&&&&&&&&&&&&&}&catch&(IOException&e1)&{
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&Chat.broadCast(String.format("System&&%s&%s",&chat.nickName,
&&&&&&&&&&&&&&&&&&&&&&&&"&has&bean&disconnection."));
&&&&&&&&&&&&}
}&& 说明: &&& 代码中ServerEndpoint注解的value值中有个nickName的参数占位符,该参数占位符称为路径参数,路径参数可以通过方法参数注解(@PathParam)进行设置并且获取;&&& 在Endpoint注解的类中OnClose,OnOpen,OnError注解的方法只有一个,OnMessage注解的方法可以有多个这个容易理解因为WebSocket可能处理的信息有text,binary,textStream等。2.客户端实现& 如果使用Maven的话,可以添加java_websocket jar的依赖。&dependency&
&&&&&&&&&&&&&groupId&org.java-websocket&/groupId&
&&&&&&&&&&&&&artifactId&Java-WebSocket&/artifactId&
&&&&&&&&&&&&&version&1.3.0&/version&
&&&&&&&&&&&&&scope&runtime&/scope&
&&&&&&&&&/dependency&& 如果开发Web客户端则可以选择支持WebSocket的浏览器,使用HTML5技术。下面是使用java_websocket来实现客户端的代码:&package&t8j8.examples.
import&java.net.URI;
import&java.net.URISyntaxE
import&java.util.S
import&org.java_websocket.client.WebSocketC
import&org.java_websocket.drafts.Draft_17;
import&org.java_websocket.handshake.ServerH
public&class&TestTocatWebSocket&{
&&&&public&static&void&main(String[]&args)&throws&URISyntaxException&{
&&&&&&&&String&url&=&"ws://localhost:/ws/chat/"&+&args[0];
&&&&&&&&WebSocketClient&wc&=&new&WebSocketClient(new&URI(url),&new&Draft_17())&{
&&&&&&&&&&&&@Override
&&&&&&&&&&&&public&void&onOpen(ServerHandshake&handshakedata)&{
&&&&&&&&&&&&&&&&System.out.println(handshakedata.getHttpStatusMessage());
&&&&&&&&&&&&}
&&&&&&&&&&&&@Override
&&&&&&&&&&&&public&void&onMessage(String&message)&{
&&&&&&&&&&&&&&&&System.out.println(message);
&&&&&&&&&&&&}
&&&&&&&&&&&&@Override
&&&&&&&&&&&&public&void&onError(Exception&ex)&{
&&&&&&&&&&&&}
&&&&&&&&&&&&@Override
&&&&&&&&&&&&public&void&onClose(int&code,&String&reason,&boolean&remote)&{
&&&&&&&&&&&&}
&&&&&&&&};
&&&&&&&&wc.connect();
&&&&&&&&while&(true)&{
&&&&&&&&&&&&Scanner&scanner&=&new&Scanner(System.in);
&&&&&&&&&&&&String&message&=&scanner.nextLine();
&&&&&&&&&&&&if&(message.equals("q"))&{
&&&&&&&&&&&&&&&&wc.close();
&&&&&&&&&&&&&&&&
&&&&&&&&&&&&}
&&&&&&&&&&&&scanner.close();
&&&&&&&&&&&&wc.send(message);
}&说明:&&& 客户端中要说明的是new Draft_17()对象的创建,通过类名可以得知草案的意思。由于Websocket标准迟迟没有发布,因而之前实现都是依据草案进行,而这里的Draft_17对应的WebSocket版本正是:【"Sec-WebSocket-Version", "13"& 】可惜,java_websocket包迟迟没有更新内容,名称出现误解人的地方。3.开始聊天& 部署服务器端程序,启动客户端程序(需要添加nickName的参数)。& 下面是聊天的截图,分别为Tom和Jack。& &至此,关于使用Tomcat8和JDK7基于WebSocket实现的聊天示例就结束了。本文出自 “” 博客,谢绝转载!
了这篇文章
类别:┆阅读(0)┆评论(0)

我要回帖

更多关于 websocket握手过程 的文章

 

随机推荐