基于JSR-356实现的Tyrus WebSocket框架的消息传递机制初步了解
对阻塞、非阻塞,同步、异步初步了解了,不是太明白,其中大多数将的是对于CPU的使用率及对一个事件的处理效率。 阻塞与非阻塞各有优缺点,在知乎上也看到了下面的结论:
在处理 IO 的时候,阻塞和非阻塞都是同步 IO。 只有使用了特殊的 API 才是异步 IO。
一、Tyrus发送消息的两种方式:
The interface javax.websocket.RemoteEndpoint, part of Java API for
WebSocket, is designed to represent the other end of the communication
(related to the endpoint), so the developer uses it to send the
There are two basic interfaces the user may use -
javax.websocket.RemoteEndpoint$Basicandjavax.websocket.RemoteEndpoint$Async.
javax.websocket.RemoteEndpoint接口,是JAVA API中的WebSocket的一部分,它被设计为与连接的另一端进行通信,开发人员可以使用它发送消息。有两种基本的接口可以使用:接口javax.websocket.RemoteEndpoint$Basic(同步消息)和javax.websocket.RemoteEndpoint$Async(异步消息)
1:同步消息传递(javax.websocket.RemoteEndpoint$Basic)
is used to send synchronous messages The point of completion of the
send is defined when all the supplied data has been written to the
underlying connection. The methods for sending messages on the
javax.websocket.RemoteEndpoint$Basic block until this point of
completion is reached, except
forjavax.websocket.RemoteEndpoint$Basic#getSendStream() and
javax.websocket.RemoteEndpoint$Basic#getSendWriter() which present
traditional blocking I/O streams to write messages. See the example
"Sending message via RemoteEndpoint.Basic instance" to see how the
whole text message is send. The following example demonstrates a
method which sends the partial text method to the peer:
javax.websocket.RemoteEndpoint$Basic接口被用来发送同步消息,当所有提供的数据都被写入到底层连接时,完成发送的标识被确定。通过javax.websocket.RemoteEndpoint$Basic接口发送消息的方法会被阻塞,直到完成发送的标识到达。javax.websocket.RemoteEndpoint$Basic#getSendStream()方法和javax.websocket.RemoteEndpoint$Basic#getSendWriter()方法 通过传统的传统的阻塞I / O流写入消息。
这里的完成发送的标识应该是方法中的isLast参数(Boolean),这里的了解的还不深入,之前一直在找WebSocket客户端处理消息的方式是什么,通过自己的几个小测试应该是多线程的。
(1)在发送同步消息时,可能一条消息被分为几次发送,相应的方法为:
例1:发送一条消息的部分消息
public void sendPartialTextMessage(String message, Boolean isLast, Session session){
try {
session.getBasicRemote().sendText(message, isLast);
} catch (IOException e) {
e.printStackTrace();
}
}
(2)发送同步消息,发送整条消息
例2:发送整条消息
@OnMessage
public void echo(String message, Session session) {
session.getBasicRemote().sendText(message);
}
这里没有说明一条完整的消息发送完是阻塞的方式还是非阻塞的方式。 如果是阻塞的方式在server-client这类型的系统中,client对于单个server在client处理相关事务时,server发送的消息就没有使用消息队列等相关的将并行消息转为串行消息的处理。
在sever-client系统中 假设一条完整的消息发送完是阻塞的,但是对于client接收到了相关消息并作出了处理,处理后又给server发送的结果消息,在消息没有标识的情况下,server是怎么知道client发送的结果消息是对应之前哪条消息的呢?
2.异步消息传递(javax.websocket.RemoteEndpoint$Async) This representation of
the peer of a web socket conversation has the ability to send messages
The point of completion of the send is defined when
the supplied data has been written to the underlying connection.
The completion handlers for the asynchronous methods are always called
with a different thread from that which initiated the send.
每一个WebSocket的端点都有异步发送消息的能力。当所有提供的数据都被写入到底层连接时,完成发送的标识被确定。异步消息处理通常是调用不同的线程来开始发送消息。
例3:使用Future异步发送消息
public void sendWholeAsyncMessage(String message, Session session){
Future<Void> future = session.getAsyncRemote().sendText(message);
}
这里讲的都是发送消息的方式,在另一端处理接收的消息并没有进行介绍,不过WebSocket是全双工通信机制,两端的接收、发送消息的方式正好相反的方式。
二、Tyrus接收消息的方式
MessagHandler(消息处理器)
Implementing the javax.websocket.MessageHandler interface is one of
the ways how to receive messages on endpoints (both server and
client). It is aimed primarily on programmatic endpoints, as the
annotated ones use the method level annotation
javax.websocket.OnMessage to denote the method which receives
messages.
实现javax.websocket.MessageHandler接口是接收消息的一种方式(服务端和客户端)。。它主要针对的编程性端点,作为注解的人使用的方法级别的注释javax.websocket.OnMessage表示接收消息的方法。
The MessageHandlers get registered on the Session instance
MessageHandlers 通过Session实例注册
There are two orthogonal criterions which classify MessageHandlers.
According the WebSocket Protocol (RFC 6455) the message may be sent
either complete, or in chunks. In Java API for WebSocket this fact is
reflected by the interface which the handler implements. Whole
messages are processed by handler which
implementsjavax.websocket.MessageHandler.Whole interface. Partial
messages are processed by handlers that implement
javax.websocket.MessageHandler.Partial interface. However, if user
registers just the whole message handler, it doesn't mean that the
handler will process solely whole messages. If partial message is
received, the parts are cached by Tyrus until the final part is
Then the whole message is passed to the handler. Similarly,
the user registers just the partial message handler and whole
message is received, it is passed directly to the handler.
MessageHandlers有两个规则。根据WebSocket协议(RFC6455)的消息可能会被发送要么完成,或发送一部分。在Java API中的WebSocket,这个规则是处理器实现的接口反射实现的。整个消息由它实现javax.websocket.MessageHandler.Whole接口处理程序进行处理。部分消息由实现javax.websocket.MessageHandler.Partial接口处理程序进行处理。但是,如果用户注册的只是整个消息的处理程序,但这并不意味着该处理器将只处理整个消息。如果接收部分消息中,部分消息由Tyrus缓存接收直到接收到整体的所有消息。然后整个消息传递给处理程序。同样地,如果用户注册的只是部分消息的处理器,这个处理器可以处理部分消息也可以处理整个消息,如果接收到的是整个的消息会直接发送给处理器。
The second criterion is the data type of the message. WebSocket
Protocol (RFC 6455) defines four message data type - text message,
According to Java API forWebSocket the text messages will be processed by MessageHandlers with
the following typesjava.lang.String
java.io.Reader
any developer object for which there is a corresponding
javax.websocket.Decoder.Text or javax.websocket.Decoder.TextStream.The binary messages will be processed by MessageHandlers with the
following types:java.nio.ByteBuffer
java.io.InputStream
any developer object for which there is a corresponding
javax.websocket.Decoder.Binary or
javax.websocket.Decoder.BinaryStream.
第二个规则是关于消息类型的。WebSocket协议(RFC-6455)规定了四种消息类型-文本消息,根据Java API中的WebSocket定义,文本消息能被消息处理器处理的类型如下:
java.lang.String
java.io.Reader
任意开发者开发的对象类型,可以通过javax.websocket.Decoder.Text 或 javax.websocket.Decoder.TextStream进行编码解码处理后进行传输、解析
能被消息处理器处理的二进制类型如下:
java.nio.ByteBuffer
java.io.InputStream
任意开发者开发的对象类型,可以通过 javax.websocket.Decoder.Binary 或 javax.websocket.Decoder.BinaryStream进行编码解码处理后进行传输、解析
注意:只能为每个类型的消息注册一个消息处理器消息类型分别为: text messages, binary messages, pong messages
到这里根据官方文档的解释及个人的理解为以上内容,介绍了发送消息的两种方式,一种为同步方式、另一种为异步方式,其中同步方式又分为将消息分为几个部分进行发送,每发送一部分消息就进行阻塞,另一种同步方式是发送一个完整的消息。
接收消息这里只介绍了每个sever端或client端中注册的消息处理器处理的消息的类型的规则。
还没有找到介绍接收消息时,对接收的消息的处理方式,多线程还是其他处理方式是否Tyrus可以进行相关的设置?
在官方文档中发现了shared client container 这一小节,这小节介绍了client端的线程池的默认设置,默认设置为一个选择线程,两个工作线程
By default, WebSocket client implementation in Tyrus re-creates client
runtime whenever WebSocketContainer#connectToServer is invoked. This
approach gives us some perks like out-of-the-box isolation and
relatively low thread count (currently we have 1 selector thread and 2
worker threads). Also it gives you the ability to stop the client
runtime – one Session instance is tied to exactly one client runtime,
so we can stop it when Session is closed. This seems as a good
solution for most of WebSocket client use cases – you usually use java
client from application which uses it for communicating with server
side and you typically don’t need more than 10 instances (my personal
estimate is that more than 90% applications won’t use more than 1
connection). There are several reasons for it – of it is just a
client, it needs to preserve server resources – one WebSocket
connection means one TCP connection and we don’t really want clients
to consume more than needed. Previous statement may be invalidated by
WebSocket multiplexing extension, but for now, it is still valid.
一个WebSocket连接就是一个TCP连接,在没有特别繁忙的消息接收的场景下不需要设置过大的线程数,只有当你确认你的程序真的需要更多的线程,推荐你设置最大线程数 设置最大线程池数的方法
client.getProperties().put(GrizzlyClientProperties.SELECTOR_THREAD_POOL_CONFIG,
ThreadPoolConfig.defaultConfig().setMaxPoolSize(3));
client.getProperties().put(GrizzlyClientProperties.WORKER_THREAD_POOL_CONFIG,
ThreadPoolConfig.defaultConfig().setMaxPoolSize(10));
(此段有待查证) 通过实验,server端单线程下按顺序发送数条消息后,client端的处理应该是 先将所有消息进行在缓冲区存储,然后逐条消息处理; server端默认不支持多线程,如果在没有修改线程池的最大并发数时,默认为1。
基于JSR-356实现的Tyrus WebSocket框架的消息传递机制初步了解的更多相关文章
- 基于动态代理的WebAPI/RPC/webSocket框架,一套接口定义,多个通讯方式
API/RPC/webSocket三个看起来好像没啥相同的地方,在开发时,服务端,客户端实现代码也大不一样 最近整理了一下,通过动态代理的形式,整合了这些开发,都通过统一的接口约束,服务端实现和客户端 ...
- webcat——基于netty的http和websocket框架
代码地址如下:http://www.demodashi.com/demo/12687.html Webcat是一个基于netty的简单.高性能服务端框架,目前提供http和websocket两种协议的 ...
- 基于TP5使用Websocket框架之GatewayWorker开发电商平台买家与卖家实时通讯
https://www.cnblogs.com/wt645631686/p/7366924.html 前段时间公司提了一个新的需求,在商品的详情页要实现站内买家和商品卖家实时通讯的功能以方便沟通促成交 ...
- PHP基于TP5使用Websocket框架之GatewayWorker开发电商平台买家与卖家实时通讯
前段时间公司提了一个新的需求,在商品的详情页要实现站内买家和商品卖家实时通讯的功能以方便沟通促成交易,要开发此功能当时首先考虑到的就是swoole和workerman了,从网上大概了解了一下关于这两款 ...
- 基于.Net平台常用的组件和框架整理
转载自:http://www.cnblogs.com/hgmyz/p/5313983.html 基于转载进行补充 RPC框架: RPC:远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而 ...
- 分布式消息总线,基于.NET Socket Tcp的发布-订阅框架之离线支持,附代码下载
一.分布式消息总线以及基于Socket的实现 在前面的分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载一文之中给大家分享和介绍了一个极其简单也非常容易上的基于.N ...
- 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载
一.分布式消息总线 在很多MIS项目之中都有这样的需求,需要一个及时.高效的的通知机制,即比如当使用者A完成了任务X,就需要立即告知使用者B任务X已经完成,在通常的情况下,开发人中都是在使用者B所使用 ...
- Entity Framework 实体框架的形成之旅--基于泛型的仓储模式的实体框架(1)
很久没有写博客了,一些读者也经常问问一些问题,不过最近我确实也很忙,除了处理日常工作外,平常主要的时间也花在了继续研究微软的实体框架(EntityFramework)方面了.这个实体框架加入了很多特性 ...
- Pomelo:网易开源基于 Node.js 的游戏服务端框架
Pomelo:网易开源基于 Node.js 的游戏服务端框架 https://github.com/NetEase/pomelo/wiki/Home-in-Chinese
随机推荐
- 普通企业的规划类项目中,OptaPlanner更适合作为APS的规划优化引擎
在企业的规划.优化场景中,均需要开发规划类的项目,实现从从种可能方案中找出相对最优方案.如排班.生产计划(包括高层次的供应链优化,到细粒度的车间甚至机台作业指令).车辆调度等.因为这类场景需要解决的问 ...
- 在docker中部署redis主从配置
环境说明: 阿里云服务器 Ubuntu 16.04 docker 1.拉取Redis镜像 docker pull redis 2.配置Redis启动配置文件,此处我创建一个专用目录,存放Redis相关 ...
- SQLAlchemy查询
SQLAlchemy查询 结果查询: from databases.wechat import User from config import session def search(): result ...
- MTK Android Driver :Battery电池曲线
MTK Android Driver :battery电池曲线 1.配置文件位置: CUSTOM_KERNEL_BATTERY= battery mediatek\custom\\kernel\bat ...
- SQL基础系列(2)-内置函数--转载w3school
1. 日期函数 Mssql: SELECT GETDATE() 返回当前日期和时间 SELECT DATEPART(yyyy,OrderDate) AS OrderYear, DATEPART( ...
- Julia基础语法字符和字符串
1.Julia字符串 2.字符
- 这届网友实在是太有才了!用python爬取15万条《我是余欢水》弹幕
年初时我们用数据解读了几部热度高,但评分差强人意的国产剧,而最近正午阳光带着两部新剧来了,<我是余欢水>和<清平乐>,截止到目前为止,这两部剧在豆瓣分别为7.5分和7.9分,算 ...
- 王者荣耀英雄全皮肤4K高清大图,python爬虫帮你保存下来
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取t.cn ...
- Python 控制流代码混淆简介,加大别人分析你代码逻辑和流程难度
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 王平 PS:如有需要Python学习资料的小伙伴可以加点击下方链接自 ...
- Feature list, Standard and Test plan for BETA Release 12/22/2015
===================BETA RELEASE FEATRURE LIST==================== 1. Log in and account manager for ...