<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

WebSocket的6種集成方式介紹

jf_ro2CN3Fa ? 來源:CSDN ? 2023-09-02 16:52 ? 次閱讀

介紹

由于前段時間我實現了一個庫【Spring Cloud】一個配置注解實現 WebSocket 集群方案

以至于我對WebSocket的各種集成方式做了一些研究

目前我所了解到的就是下面這些了(就一個破ws都有這么多花里胡哨的集成方式了?)

Javax

WebMVC

WebFlux

Java-WebSocket

SocketIO

Netty

今天主要介紹一下前3種方式,畢竟現在的主流框架還是Spring Boot

而后3種其實和Spring Boot并不強行綁定,基于Java就可以支持,不過我也會對后3種做個簡單的介紹,大家先混個眼熟就行了

那么接下來我們就來講講前3種方式(Javax,WebMVC,WebFlux)在Spring Boot中的服務端和客戶端配置(客戶端配置也超重要的有木有,平時用不到,用到了卻基本找不到文檔,這也太絕望了)

Javax

在java的擴展包javax.websocket中就定義了一套WebSocket的接口規范

服務端

一般使用注解的方式來進行配置

第一步

@Component
@ServerEndpoint("/websocket/{type}")
publicclassJavaxWebSocketServerEndpoint{

@OnOpen
publicvoidonOpen(Sessionsession,EndpointConfigconfig,
@PathParam(value="type")Stringtype){
//連接建立
}

@OnClose
publicvoidonClose(Sessionsession,CloseReasonreason){
//連接關閉
}

@OnMessage
publicvoidonMessage(Sessionsession,Stringmessage){
//接收文本信息
}

@OnMessage
publicvoidonMessage(Sessionsession,PongMessagemessage){
//接收pong信息
}

@OnMessage
publicvoidonMessage(Sessionsession,ByteBuffermessage){
//接收二進制信息,也可以用byte[]接收
}

@OnError
publicvoidonError(Sessionsession,Throwablee){
//異常處理
}
}

我們在類上添加@ServerEndpoint注解來表示這是一個服務端點,同時可以在注解中配置路徑,這個路徑可以配置成動態的,使用{}包起來就可以了

@OnOpen用來標記對應的方法作為客戶端連接上來之后的回調,Session就相當于和客戶端的連接啦,我們可以把它緩存起來用于發送消息;通過@PathParam注解就可以獲得動態路徑中對應值了

@OnClose用來標記對應的方法作為客戶端斷開連接之后的回調,我們可以在這個方法中移除對應Session的緩存,同時可以接受一個CloseReason的參數用于獲取關閉原因

@OnMessage用來標記對應的方法作為接收到消息之后的回調,我們可以接受文本消息,二進制消息和pong消息

@OnError用來標記對應的方法作為拋出異常之后的回調,可以獲得對應的Session和異常對象

第二步

implementation'org.springframework.boot:spring-boot-starter-websocket'
@Configuration(proxyBeanMethods=false)
publicclassJavaxWebSocketConfiguration{

@Bean
publicServerEndpointExporterserverEndpointExporter(){
returnnewServerEndpointExporter();
}
}

依賴Spring的WebSocket模塊,手動注入ServerEndpointExporter就可以了

需要注意ServerEndpointExporter是Spring中的類,算是Spring為了支持javax.websocket的原生用法所提供的支持類

冷知識

javax.websocket庫中定義了PongMessage而沒有PingMessage

通過我的測試發現基本上所有的WebSocket包括前端js自帶的,都實現了自動回復;也就是說當接收到一個ping消息之后,是會自動回應一個pong消息,所以沒有必要再自己接受ping消息來處理了,即我們不會接受到ping消息

當然我上面講的ping和pong都是需要使用框架提供的api,如果是我們自己通過Message來自定義心跳數據的話是沒有任何的處理的,下面是對應的api

//發送ping
session.getAsyncRemote().sendPing(ByteBufferbuffer);

//發送pong
session.getAsyncRemote().sendPong(ByteBufferbuffer);

然后我又發現js自帶的WebSocket是沒有發送ping的api的,所以是不是可以猜想當初就是約定服務端發送ping,客戶端回復pong

客戶端

客戶端也是使用注解配置

第一步

@ClientEndpoint
publicclassJavaxWebSocketClientEndpoint{

@OnOpen
publicvoidonOpen(Sessionsession){
//連接建立
}

@OnClose
publicvoidonClose(Sessionsession,CloseReasonreason){
//連接關閉
}

@OnMessage
publicvoidonMessage(Sessionsession,Stringmessage){
//接收文本消息
}

@OnMessage
publicvoidonMessage(Sessionsession,PongMessagemessage){
//接收pong消息
}

@OnMessage
publicvoidonMessage(Sessionsession,ByteBuffermessage){
//接收二進制消息
}

@OnError
publicvoidonError(Sessionsession,Throwablee){
//異常處理
}
}

客戶端使用@ClientEndpoint來標記,其他的@OnOpen,@OnClose,@OnMessage,@OnError和服務端一模一樣

第二步

WebSocketContainercontainer=ContainerProvider.getWebSocketContainer();
Sessionsession=container.connectToServer(JavaxWebSocketClientEndpoint.class,uri);

我們可以通過ContainerProvider來獲得一個WebSocketContainer,然后調用connectToServer方法將我們的客戶端類和連接的uri傳入就行了

冷知識

通過ContainerProvider#getWebSocketContainer獲得WebSocketContainer其實是基于SPI實現的

在Spring的環境中我更推薦大家使用ServletContextAware來獲得,代碼如下

@Component
publicclassJavaxWebSocketContainerimplementsServletContextAware{

privatevolatileWebSocketContainercontainer;

publicWebSocketContainergetContainer(){
if(container==null){
synchronized(this){
if(container==null){
container=ContainerProvider.getWebSocketContainer();
}
}
}
returncontainer;
}

@Override
publicvoidsetServletContext(@NonNullServletContextservletContext){
if(container==null){
container=(WebSocketContainer)servletContext
.getAttribute("javax.websocket.server.ServerContainer");
}
}
}

發消息

Sessionsession=...

//發送文本消息
session.getAsyncRemote().sendText(Stringmessage);

//發送二進制消息
session.getAsyncRemote().sendBinary(ByteBuffermessage);

//發送對象消息,會嘗試使用Encoder編碼
session.getAsyncRemote().sendObject(Objectmessage);

//發送ping
session.getAsyncRemote().sendPing(ByteBufferbuffer);

//發送pong
session.getAsyncRemote().sendPong(ByteBufferbuffer);

WebMVC

依賴肯定是必不可少的

implementation'org.springframework.boot:spring-boot-starter-websocket'

服務端

第一步

importorg.springframework.web.socket.WebSocketHandler;
importorg.springframework.web.socket.WebSocketMessage;
importorg.springframework.web.socket.WebSocketSession;

publicclassServletWebSocketServerHandlerimplementsWebSocketHandler{

@Override
publicvoidafterConnectionEstablished(@NonNullWebSocketSessionsession)throwsException{
//連接建立
}

@Override
publicvoidhandleMessage(@NonNullWebSocketSessionsession,@NonNullWebSocketMessagemessage)throwsException{
//接收消息
}

@Override
publicvoidhandleTransportError(@NonNullWebSocketSessionsession,@NonNullThrowableexception)throwsException{
//異常處理
}

@Override
publicvoidafterConnectionClosed(@NonNullWebSocketSessionsession,@NonNullCloseStatuscloseStatus)throwsException{
//連接關閉
}

@Override
publicbooleansupportsPartialMessages(){
//是否支持接收不完整的消息
returnfalse;
}
}

我們實現一個WebSocketHandler來處理WebSocket的連接,關閉,消息和異常

第二步

@Configuration
@EnableWebSocket
publicclassServletWebSocketServerConfigurerimplementsWebSocketConfigurer{

@Override
publicvoidregisterWebSocketHandlers(@NonNullWebSocketHandlerRegistryregistry){
registry
//添加處理器到對應的路徑
.addHandler(newServletWebSocketServerHandler(),"/websocket")
.setAllowedOrigins("*");
}
}

首先需要添加@EnableWebSocket來啟用WebSocket

然后實現WebSocketConfigurer來注冊WebSocket路徑以及對應的WebSocketHandler

握手攔截

提供了HandshakeInterceptor來攔截握手

@Configuration
@EnableWebSocket
publicclassServletWebSocketServerConfigurerimplementsWebSocketConfigurer{

@Override
publicvoidregisterWebSocketHandlers(@NonNullWebSocketHandlerRegistryregistry){
registry
//添加處理器到對應的路徑
.addHandler(newServletWebSocketServerHandler(),"/websocket")
//添加握手攔截器
.addInterceptors(newServletWebSocketHandshakeInterceptor())
.setAllowedOrigins("*");
}

publicstaticclassServletWebSocketHandshakeInterceptorimplementsHandshakeInterceptor{

@Override
publicbooleanbeforeHandshake(ServerHttpRequestrequest,ServerHttpResponseresponse,WebSocketHandlerwsHandler,Mapattributes)throwsException{
//握手之前
//繼續握手返回true,中斷握手返回false
returnfalse;
}

@Override
publicvoidafterHandshake(ServerHttpRequestrequest,ServerHttpResponseresponse,WebSocketHandlerwsHandler,Exceptionexception){
//握手之后
}
}
}

冷知識

我在集成的時候發現這種方式沒辦法動態匹配路徑,它的路徑就是固定的,沒辦法使用如/websocket/**這樣的通配符

我在研究了一下之后發現可以在UrlPathHelper上做點文章

@Configuration
@EnableWebSocket
publicclassServletWebSocketServerConfigurerimplementsWebSocketConfigurer{

@Override
publicvoidregisterWebSocketHandlers(@NonNullWebSocketHandlerRegistryregistry){
if(registryinstanceofServletWebSocketHandlerRegistry){
//替換UrlPathHelper
((ServletWebSocketHandlerRegistry)registry)
.setUrlPathHelper(newPrefixUrlPathHelper("/websocket"));
}

registry
//添加處理器到對應的路徑
.addHandler(newServletWebSocketServerHandler(),"/websocket/**")
.setAllowedOrigins("*");
}

publicclassPrefixUrlPathHelperextendsUrlPathHelper{

privateStringprefix;

@Override
public@NonNullStringresolveAndCacheLookupPath(@NonNullHttpServletRequestrequest){
//獲得原本的Path
Stringpath=super.resolveAndCacheLookupPath(request);
//如果是指定前綴就返回對應的通配路徑
if(path.startsWith(prefix)){
returnprefix+"/**";
}
returnpath;
}
}
}

因為它內部實際上就是用一個Map來存的,所以沒有辦法用通配符

主要是有現成的AntPathMatcher實現通配應該不麻煩才對啊

客戶端

第一步

publicclassServletWebSocketClientHandlerimplementsWebSocketHandler{

@Override
publicvoidafterConnectionEstablished(@NonNullWebSocketSessionsession)throwsException{
//連接建立
}

@Override
publicvoidhandleMessage(@NonNullWebSocketSessionsession,@NonNullWebSocketMessagemessage)throwsException{
//接收消息
}

@Override
publicvoidhandleTransportError(@NonNullWebSocketSessionsession,@NonNullThrowableexception)throwsException{
//異常處理
}

@Override
publicvoidafterConnectionClosed(@NonNullWebSocketSessionsession,@NonNullCloseStatuscloseStatus)throwsException{
//連接關閉
}

@Override
publicbooleansupportsPartialMessages(){
//是否支持接收不完整的消息
returnfalse;
}
}

和服務端一樣我們需要先實現一個WebSocketHandler來處理WebSocket的連接,關閉,消息和異常

第二步

WebSocketClientclient=newStandardWebSocketClient();
WebSocketHandlerhandler=newServletWebSocketClientHandler();
WebSocketConnectionManagermanager=newWebSocketConnectionManager(client,handler,uri);
manager.start();

首先我們需要先new一個StandardWebSocketClient,可以傳入一個WebSocketContainer參數,獲得該對象的方式我之前已經介紹過了,這邊就先略過

然后new一個WebSocketConnectionManager傳入WebSocketClient,WebSocketHandler還有路徑uri

最后調用一下WebSocketConnectionManager的start方法就可以啦

冷知識

這里如果大家去看WebSocketClient的實現類就會發現有StandardWebSocketClient還有JettyWebSocketClient等等,所以大家可以根據自身項目所使用的容器來選擇不同的WebSocketClient實現類

這里給大家貼一小段Spring適配不同容器WebSocket的代碼

publicabstractclassAbstractHandshakeHandlerimplementsHandshakeHandler,Lifecycle{

privatestaticfinalbooleantomcatWsPresent;

privatestaticfinalbooleanjettyWsPresent;

privatestaticfinalbooleanjetty10WsPresent;

privatestaticfinalbooleanundertowWsPresent;

privatestaticfinalbooleanglassfishWsPresent;

privatestaticfinalbooleanweblogicWsPresent;

privatestaticfinalbooleanwebsphereWsPresent;

static{
ClassLoaderclassLoader=AbstractHandshakeHandler.class.getClassLoader();
tomcatWsPresent=ClassUtils.isPresent(
"org.apache.tomcat.websocket.server.WsHttpUpgradeHandler",classLoader);
jetty10WsPresent=ClassUtils.isPresent(
"org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer",classLoader);
jettyWsPresent=ClassUtils.isPresent(
"org.eclipse.jetty.websocket.server.WebSocketServerFactory",classLoader);
undertowWsPresent=ClassUtils.isPresent(
"io.undertow.websockets.jsr.ServerWebSocketContainer",classLoader);
glassfishWsPresent=ClassUtils.isPresent(
"org.glassfish.tyrus.servlet.TyrusHttpUpgradeHandler",classLoader);
weblogicWsPresent=ClassUtils.isPresent(
"weblogic.websocket.tyrus.TyrusServletWriter",classLoader);
websphereWsPresent=ClassUtils.isPresent(
"com.ibm.websphere.wsoc.WsWsocServerContainer",classLoader);
}
}

發消息

importorg.springframework.web.socket.*;

WebSocketSessionsession=...

//發送文本消息
session.sendMessage(newTextMessage(CharSequencemessage);

//發送二進制消息
session.sendMessage(newBinaryMessage(ByteBuffermessage));

//發送ping
session.sendMessage(newPingMessage(ByteBuffermessage));

//發送pong
session.sendMessage(newPongMessage(ByteBuffermessage));

WebFlux

WebFlux的WebSocket不需要額外的依賴包

服務端

第一步

importorg.springframework.web.reactive.socket.WebSocketHandler;
importorg.springframework.web.reactive.socket.WebSocketSession;

publicclassReactiveWebSocketServerHandlerimplementsWebSocketHandler{

@NonNull
@Override
publicMonohandle(WebSocketSessionsession){
Monosend=session.send(Flux.create(sink->{
//可以持有sink對象在任意時候調用next發送消息
sink.next(WebSocketMessagemessage);
})).doOnError(it->{
//異常處理
});

Monoreceive=session.receive()
.doOnNext(it->{
//接收消息
})
.doOnError(it->{
//異常處理
})
.then();

@SuppressWarnings("all")
Disposabledisposable=session.closeStatus()
.doOnError(it->{
//異常處理
})
.subscribe(it->{
//連接關閉
});

returnMono.zip(send,receive).then();
}
}

首先需要注意這里的WebSocketHandler和WebSocketSession是reactive包下的

通過WebSocketSession#send方法來持有一個FluxSink來用于發送消息

通過WebSocketSession#receive來訂閱消息

通過WebSocketSession#closeStatus來訂閱連接關閉事件

第二步

@Component
publicclassReactiveWebSocketServerHandlerMappingextendsSimpleUrlHandlerMapping{

publicReactiveWebSocketServerHandlerMapping(){
Mapmap=newHashMap<>();
map.put("/websocket/**",newReactiveWebSocketServerHandler());
setUrlMap(map);
setOrder(100);
}
}

注冊一個HandlerMapping同時配置路徑和對應的WebSocketHandler

第三步

@Configuration(proxyBeanMethods=false)
publicclassReactiveWebSocketConfiguration{

@Bean
publicWebSocketHandlerAdapterwebSocketHandlerAdapter(){
returnnewWebSocketHandlerAdapter();
}
}

注入WebSocketHandlerAdapter

冷知識

我們自定義的HandlerMapping需要設置order,如果不設置,默認為Ordered.LOWEST_PRECEDENCE,會導致這個HandlerMapping被放在最后,當有客戶端連接上來時會被其他的HandlerMapping優先匹配上而連接失敗

客戶端

第一步

publicclassReactiveWebSocketClientHandlerimplementsWebSocketHandler{

@NonNull
@Override
publicMonohandle(WebSocketSessionsession){
Monosend=session.send(Flux.create(sink->{
//可以持有sink對象在任意時候調用next發送消息
sink.next(WebSocketMessagemessage);
})).doOnError(it->{
//處理異常
});

Monoreceive=session.receive()
.doOnNext(it->{
//接收消息
})
.doOnError(it->{
//異常處理
})
.then();

@SuppressWarnings("all")
Disposabledisposable=session.closeStatus()
.doOnError(it->{
//異常處理
})
.subscribe(it->{
//連接關閉
});

returnMono.zip(send,receive).then();
}
}

客戶端WebSocketHandler的寫法和服務端的一樣

第二步

importorg.springframework.web.reactive.socket.client.WebSocketClient;

WebSocketClientclient=ReactorNettyWebSocketClient();
WebSocketHandlerhandler=newReactiveWebSocketClientHandler();
client.execute(uri,handler).subscribe();

首先我們需要先new一個ReactorNettyWebSocketClient

然后調用一下WebSocketClient的execute方法傳入路徑uri和WebSocketHandler并繼續調用subscribe方法就行啦

冷知識

和WebMVC中的WebSocketClient一樣,Reactive包中的WebSocketClient也有很多實現類,比如ReactorNettyWebSocketClient,JettyWebSocketClient,UndertowWebSocketClient,TomcatWebSocketClient等等,也是需要大家基于自身項目的容器使用不同的實現類

這里也給大家貼一小段Reactive適配不同容器WebSocket的代碼

publicclassHandshakeWebSocketServiceimplementsWebSocketService,Lifecycle{

privatestaticfinalbooleantomcatPresent;

privatestaticfinalbooleanjettyPresent;

privatestaticfinalbooleanjetty10Present;

privatestaticfinalbooleanundertowPresent;

privatestaticfinalbooleanreactorNettyPresent;

static{
ClassLoaderloader=HandshakeWebSocketService.class.getClassLoader();
tomcatPresent=ClassUtils.isPresent("org.apache.tomcat.websocket.server.WsHttpUpgradeHandler",loader);
jettyPresent=ClassUtils.isPresent("org.eclipse.jetty.websocket.server.WebSocketServerFactory",loader);
jetty10Present=ClassUtils.isPresent("org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer",loader);
undertowPresent=ClassUtils.isPresent("io.undertow.websockets.WebSocketProtocolHandshakeHandler",loader);
reactorNettyPresent=ClassUtils.isPresent("reactor.netty.http.server.HttpServerResponse",loader);
}
}

發消息

我們需要使用在WebSocketHandler中獲得的FluxSink來發送消息

importorg.springframework.web.reactive.socket.CloseStatus;
importorg.springframework.web.reactive.socket.WebSocketMessage;
importorg.springframework.web.reactive.socket.WebSocketSession;

publicclassReactiveWebSocket{

privatefinalWebSocketSessionsession;

privatefinalFluxSinksender;

publicReactiveWebSocket(WebSocketSessionsession,FluxSinksender){
this.session=session;
this.sender=sender;
}

publicStringgetId(){
returnsession.getId();
}

publicURIgetUri(){
returnsession.getHandshakeInfo().getUri();
}

publicvoidsend(Objectmessage){
if(messageinstanceofWebSocketMessage){
sender.next((WebSocketMessage)message);
}elseif(messageinstanceofString){
//發送文本消息
sender.next(session.textMessage((String)message));
}elseif(messageinstanceofDataBuffer){
//發送二進制消息
sender.next(session.binaryMessage(factory->(DataBuffer)message));
}elseif(messageinstanceofByteBuffer){
發送二進制消息
sender.next(session.binaryMessage(factory->factory.wrap((ByteBuffer)message)));
}elseif(messageinstanceofbyte[]){
發送二進制消息
sender.next(session.binaryMessage(factory->factory.wrap((byte[])message)));
}else{
thrownewIllegalArgumentException("Messagetypenotmatch");
}
}

publicvoidping(){
//發送ping
sender.next(session.pingMessage(factory->factory.wrap(ByteBuffer.allocate(0))));
}

publicvoidpong(){
//發送pong
sender.next(session.pongMessage(factory->factory.wrap(ByteBuffer.allocate(0))));
}

publicvoidclose(CloseStatusreason){
sender.complete();
session.close(reason).subscribe();
}
}

Java-WebSocket

這是一個純java的第三方庫,專門用于實現WebSocket

SocketIO

該庫使用的協議是經過自己封裝的,支持很多的語言,提供了統一的接口,所以需要使用它提供的Server和Client來連接,如socket.io-server-java和socket.io-client-java

這個庫我了解下來主要用于實時聊天等場景,所以如果只是普通的WebSocket功能就有點大材小用了

Netty

這個大家應該都比較熟悉了,就算沒用過肯定也聽過

網上的文檔和示例也非常多,我這里就不介紹有的沒的了,Github傳送門。






審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 二進制
    +關注

    關注

    2

    文章

    709

    瀏覽量

    41266
  • JAVA語言
    +關注

    關注

    0

    文章

    138

    瀏覽量

    19944
  • 緩存器
    +關注

    關注

    0

    文章

    63

    瀏覽量

    11580
  • WebSocket
    +關注

    關注

    0

    文章

    24

    瀏覽量

    3657

原文標題:WebSocket 的 6 種集成方式

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    白光LED形成方式

    白光LED形成方式
    發表于 08-20 21:15

    ORCAD與PLM集成方

    ORCAD與PLM集成方
    發表于 07-07 14:59

    求一基于FPGA的A型數字式超聲系統的構成方式

    簡略介紹了超聲探傷的基本原理,并在此基礎上提出了一基于FPGA的A型數字式超聲系統的構成方式,著重介紹了系統的硬件構成。其中,基于FPGA的數字信號處理模塊從根本上解決了傳統A型探傷
    發表于 05-06 08:38

    SPWM信號主要有3成方式

    描述目前,SPWM信號主要有3成方式:1)使用比較器、振蕩器等模擬電路產生三角波和方波進行比較,產生SPWM波,但是此種方法電路復雜,受元器件精度影響大,且不易控制;2)利用專用SPWM集成芯片
    發表于 11-15 08:01

    基于TCP的一新的網絡協議WebSocket

    開啟 WebSocket 服務WebSocket 服務是網頁程序、安卓 App、微信小程序等獲得數據和服務的接口,是基于TCP 的一新的網絡協議,它實現了瀏覽器與服務器全雙工通信。通過
    發表于 12-16 07:38

    RK集成系統apk的集成方式該怎樣去實現呢

    RK集成系統apk相對于MTK的集成方式有何優點?RK集成系統apk的集成方式該怎樣去實現呢?
    發表于 02-18 07:44

    智能建筑系統集成方式的研究及應用

    本文通過闡述智能建筑系統集成層次劃分的概念,分析了現存的四種系統集成方式的特點及存在的問題,提出了模塊并行集成模式和基于OPC 的組件化集成模式兩種智能建筑系統
    發表于 06-16 11:32 ?17次下載

    語音合成方式與原理電路圖

    語音合成方式與原理電路圖
    發表于 07-20 11:53 ?586次閱讀
    語音合<b class='flag-5'>成方式</b>與原理電路圖

    什么是WebSocket?進行通信解析 WebSocket 報文及實現

    一般情況下全為 0。當客戶端、服務端協商采用 WebSocket 擴展時,這三個標志位可以非0,且值的含義由擴展進行定義。如果出現非零的值,且并沒有采用 WebSocket 擴展,連接出錯。
    的頭像 發表于 05-15 16:59 ?9191次閱讀
    什么是<b class='flag-5'>WebSocket</b>?進行通信解析 <b class='flag-5'>WebSocket</b> 報文及實現

    WebSocket有什么優點

    WebSocket是一種在單個TCP連接上進行全雙工通信的協議。WebSocket通信協議于2011年被IETF定為標準RFC 6455,并由RFC7936補充規范。WebSocket API也被W3C定為標準。HTML5開始提
    的頭像 發表于 02-15 15:53 ?7978次閱讀
    <b class='flag-5'>WebSocket</b>有什么優點

    WebSocket工作原理及使用方法

    它有很多名字; WebSocket,WebSocket協議和WebSocket API。從首選的消息傳遞應用程序到流行的在線多人游戲,WebSocket在當今最常用的Web應用程序中是
    的頭像 發表于 05-05 22:12 ?7548次閱讀
    <b class='flag-5'>WebSocket</b>工作原理及使用方法

    安防系統集成方式

    集成方式屬于系統級的"半軟"集成方式,各子系統之間通過串口連接形式進行通信。在原有系統的基礎上,不需增加任何硬件設備,也不需要進行任何二次開發工作,即可構建一個安防集成系統,實現防區內各應用子系統的聯動。
    的頭像 發表于 05-15 09:23 ?7684次閱讀

    鴻蒙上WebSocket的使用方法

    WebSocket 是一種網絡通訊協議,很多網絡開發工作者都需要它。本文介紹在 OpenHarmony 上 WebSocket 協議的使用方法。
    的頭像 發表于 03-08 14:17 ?999次閱讀

    電力運維監控系統集成方

    電力運維監控系統集成方
    的頭像 發表于 11-25 15:21 ?762次閱讀
    電力運維監控系統<b class='flag-5'>集成方</b>案

    websocket協議的原理

    WebSocket協議是基于TCP的一種新的網絡協議。它實現了瀏覽器與服務器全雙工(full-duplex)通信——允許服務器主動發送信息給客戶端。 WebSocket通信協議于2011年被IETF
    的頭像 發表于 11-09 15:13 ?434次閱讀
    <b class='flag-5'>websocket</b>協議的原理
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>