在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

    文章

    803

    瀏覽量

    42012
  • JAVA語言
    +關注

    關注

    0

    文章

    138

    瀏覽量

    20436
  • 緩存器
    +關注

    關注

    0

    文章

    63

    瀏覽量

    11790
  • WebSocket
    +關注

    關注

    0

    文章

    30

    瀏覽量

    3951

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

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

收藏 人收藏

    評論

    相關推薦

    淺談集成FPGA的兩方式:eFPGA(SoC)&amp; cFPGA(SiP)

    目前流行的兩集成方案分別是embedded FPGA(以下簡稱eFPGA集成方案)以及FPGA Chiplets(以下簡稱cFPGA集成方案)1.eFPGA
    的頭像 發表于 08-16 09:53 ?7522次閱讀
    淺談<b class='flag-5'>集成</b>FPGA的兩<b class='flag-5'>種</b><b class='flag-5'>方式</b>:eFPGA(SoC)&amp; cFPGA(SiP)

    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

    基于凸殼算法的SVM集成方

    為提高支持向量機(SVM)集成的訓練速度,提出一基于凸殼算法的SVM 集成方法,得到訓練集各類數據的殼向量,將其作為基分類器的訓練集,并采用Bagging 策略集成各個SVM。在訓
    發表于 04-16 11:43 ?10次下載

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

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

    BACnet網絡與Internet的集成方

    BACnet是開放的樓宇設備自動控制網絡數據通信協議。隨著Internet在通信領域的發展,控制網絡與Internet的集成已是必然趨勢。本文給出了一BACnet-TCP/IP集成方案,并詳細敘述了方
    發表于 02-22 11:34 ?27次下載

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

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

    WebSocket有什么優點

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

    鴻蒙上WebSocket的使用方法

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

    websocket協議的原理

    WebSocket協議是基于TCP的一新的網絡協議。它實現了瀏覽器與服務器全雙工(full-duplex)通信——允許服務器主動發送信息給客戶端。 WebSocket通信協議于2011年被IETF
    的頭像 發表于 11-09 15:13 ?1457次閱讀
    <b class='flag-5'>websocket</b>協議的原理

    萬界星空科技MES數據的集成方式

    MES系統與其他系統常見的集成方式。根據實際需求和系統環境,選擇適合的集成方式可以實現不同系統之間的協同工作,提高生產效率和管理水平。具體的集成方式可能因企業和行業的不同而有所差異。
    的頭像 發表于 10-09 15:30 ?285次閱讀
    萬界星空科技MES數據的<b class='flag-5'>集成方式</b>

    AWTK-WEB 快速入門(6) - JS WebSocket 應用程序

    WebSocket可以實現雙向通信,適合實時通信場景。本文介紹一下使用Javacript語言開發AWTK-WEB應用程序,并用WebSocket與服務器通訊。用AWTKDesigner新建一個應用程
    的頭像 發表于 02-26 11:42 ?227次閱讀
    AWTK-WEB 快速入門(<b class='flag-5'>6</b>) - JS <b class='flag-5'>WebSocket</b> 應用程序
    主站蜘蛛池模板: 天天搞夜夜 | 亚洲美女爱爱 | 久久精品福利 | 国产一区二区三区欧美精品 | 色婷婷5月精品久久久久 | 成人久久久精品乱码一区二区三区 | 久久综合成人网 | 国产成人在线影院 | 天天干在线播放 | 丁香六月色婷婷 | 国产在线视频h | 亚洲最大的黄色网址 | 18岁禁黄色 | 福利在线看片 | 精品久久久久久久久久 | 午夜在线播放 | 色偷偷亚洲综合网亚洲 | 中文字幕一区二区三 | 国产精品一区在线播放 | 免费爱爱小视频 | 97人人射| 欧美爱爱帝国综合社区 | 日本视频一区二区三区 | 天天综合五月天 | 亚洲天堂免费观看 | sss欧美华人整片在线观看 | 欧美一级淫片免费播放口 | 91精品啪国产在线观看免费牛牛 | se97se成人亚洲网站在线观看 | 黄网站在线播放 | 国产大片免费观看中文字幕 | 三级不卡 | 在线观看国产日本 | 高清视频 一区二区三区四区 | 亚洲人成亚洲人成在线观看 | 国产在线一区二区三区四区 | 日本xxxxxxx69xx| 你懂的在线观看网址 | 欧美成人观看免费全部完小说 | 精品二区 | 丁香六月五月婷婷 |