搭建websocket服务器,php创建websocket客户端
C++如何搭建Web服务端(WebSocketpp)
C++使用WebSocket++搭建Web服务端的方法及步骤:
WebSocket++是一种C++实现的WebSocket库,具有头文件仅需包含、C++11语法支持、多种网络传输模块可选、线程安全、安全性和代理支持等特性。借助它,C++开发者可以轻松集成WebSocket功能到自己的应用中。
为了使用WebSocket++,开发者需先确保环境安装了必要的依赖库,比如Boost和OpenSSL。安装步骤包括下载ActivePerl以执行Perl脚本并配置OpenSSL,以及安装Netwide Assembler(NASM)用于OpenSSL的汇编编译。ActivePerl和NASM的安装路径应添加到环境变量中,确保OpenSSL和其他工具的正确访问。
具体安装时,检查Perl和NASM是否已成功安装,并确认其路径正确无误。完成安装后,通过参考相应的`install.win32`文件(在OpenSSL下载源目录中),将OpenSSL的头文件和库文件加入到项目工程中。同样,遵循Boost源代码内的`install`文档进行Boost的编译步骤。
在配置VS2015创建的控制台项目时,引入WebSocketpp的头文件路径至关重要,避免出现找不到头文件路径的警告。例如,可以将`websocketpp`目录添加到项目中,以便正确编译和链接所需库。
将WebSocket++相关的源代码项目进行本地配置,并将其编译成.exe文件。对于编译过程中可能出现的警告(如未分配的值),通常可以忽略,因为它在构建过程中是由于编译器策略所导致的,而不是代码存在问题。
在成功编译并运行项目时,若未见到正常输出,可能原因在于项目的启动方式。默认情况下,WebSocket++可能采用`boost::asio`初始化网络,并监听端口9002接收数据。为了测试项目功能,可将默认参数更改并测试其反馈。使用浏览器访问相应的URL(如`127.0.0.1:9002`并发送请求),应能查看到数据交换情况。
为了验证WebSocket++发送和接收数据的功能,可以参考特定的示例代码,将其整合至项目中。通过发送不同的消息测试服务器的响应,以确定WebSocket++正确地实现消息的传输。
总的来说,WebSocket++为C++开发者提供了一个高效的WebSocket功能实现,简化了开发流程并提高了开发效率。正确地准备环境、配置代码并进行充分测试,有助于确保WebSocket++能在实际应用中稳定运行,实现预期的网络通信功能。
socket.io搭建websocket服务器
Socket.IO是一个库,可以在客户端和服务器之间实现低延迟、双向和基于事件的通信。
它建立在WebSocket协议之上,并提供额外的保证,例如回退到 HTTP长轮询或自动重新连接。
注意: Socket.IO不是WebSocket实现。也就是说我们不能通过new WebSocket(URL)的方式来连接服务端,必须使用其提供的客户端的socket.io-client来链接socket.io创建的服务。
尽管Socket.io在可能的情况下使用WebSocket进行传输,但它为每个数据包,添加了额外的元数据,这就是为什么WebSocket客户端将无法成功连接到`Socket.IO服务器。
服务器yarn add socket.io
用法:
const{ Server}= require('socket.io')const io= new Server({/* options*/})io.on('connection', socket=>{//...})io.listen(3000)
或者将端口做为第一个参数传递个Service。
const{ Server}= require('socket.io')const io= new Server(3000,{/* options*/})io.on('connection', socket=>{//...})和 Koa一起使用const Koa= require('koa')const{ createServer}= require('http')const{ Server}= require('socket.io')const app= new Koa()const httpServer= createServer(app.callback())const io= new Server(httpServer,{/* options*/})io.on('connection', socket=>{//...})httpServer.listen(3000)处理 CORS
从 Socket.IO v3开始,您需要显式启用跨域资源共享(CORS)。
import{ createServer} from'http'import{ Server} from'socket.io'const httpServer= createServer()const io= new Server(httpServer,{cors:{origin:''//或者使用*}})中间件
注册中间件:
io.use((socket, next)=>{const toekn= socket.handshake.auth.tokenif(toekn){next()} else{next(new Error('invalid'))}})
可以注册多个中间件,他们按照注册的顺序执行。
客户端安装yarn add socket.io-client建立连接const socket= io('',{reconnection: true,//是否重连reconnectionAttempts: 30,//重新连接的次数reconnectionDelay: 1000,//每过多长时间重连一次timeout: 5000,//超时时间auth:{token: window.sessionStorage.getItem('token')}})事件
connect:在连接和重新连接的时候会被触发。
socket.on('connect',()=>{ console.log('连接成功')})
connect:在无法和服务器建立连接的时候触发,例如网络或者服务器拒绝连接。由于网络原因引起的会执行自动重连,但是服务器拒绝连接的需要手动调用重新连接。
/***在无法和服务器建立连接的时候触发(网络原因/服务器拒绝)*网络原因:会执行自动重连*服务器拒接连接:需要手动重新连接**/socket.on('connect_error', error=>{ console.error('连接出错==>', error.message, error.data?.content) if(error.message==='not authorized'){ clearTimeout(connect_timer) connect_timer= setTimeout(()=>{ socket.auth.token= window.sessionStorage.getItem('token') socket.connect()}, 4000)}})
disconnect:在连接断开的时候触发,例如刷新页面,手动断开连接等等。
const{ Server}= require('socket.io')const io= new Server({/* options*/})io.on('connection', socket=>{//...})io.listen(3000)0
其余的事件均为自定义事件,使用socket.io(事件名,callback)来监听。例如:
const{ Server}= require('socket.io')const io= new Server({/* options*/})io.on('connection', socket=>{//...})io.listen(3000)1发送数据const{ Server}= require('socket.io')const io= new Server({/* options*/})io.on('connection', socket=>{//...})io.listen(3000)2
基本上常用的就这些,我也是把一些常用的 API实践总结了一下,具体更详细的使用可以去查询官方文档
案例
最后贴一下服务端和客户端的两个 demo:
服务器
这一段代码是添加在使用 Koa+ TS+ ESLlint搭建 node服务器中main.ts中的代码
const{ Server}= require('socket.io')const io= new Server({/* options*/})io.on('connection', socket=>{//...})io.listen(3000)3客户端const{ Server}= require('socket.io')const io= new Server({/* options*/})io.on('connection', socket=>{//...})io.listen(3000)4原文:
使用netty搭建websocket客户端
简介
在网速快速提升的时代,浏览器已经成为我们访问各种服务的入口,很难想象如果离开了浏览器,我们的网络世界应该如何运作。现在恨不得把操作系统都搬上浏览器。但是并不是所有的应用都需要浏览器来执行,比如服务器和服务器之间的通信,就需要使用到自建客户端来和服务器进行交互。
本文将会介绍使用Netty客户端连接WebSocket的原理和具体实现。
浏览器客户端
在介绍netty客户端之前,我们先看一个简单的浏览器客户端连接websocket的例子:
//创建连接constsocket=newWebSocket('ws://localhost:8000');//开启连接socket.addEventListener('open',function(event){socket.send('没错,开启了!');});//监听消息socket.addEventListener('message',function(event){console.log('监听到服务器的消息',event.data);});
这里使用了浏览器最通用的语言javascript,并使用了浏览器提供的websocketAPI进行操作,非常的简单。
那么用netty客户端实现websocket的连接是否和javascript使用一样呢?我们一起来探索。
netty对websocket客户端的支持
先看看netty对websocket的支持类都有哪些,接着我们看下怎么具体去使用这些工具类。
WebSocketClientHandshaker
和websocketserver一样,client中最核心的类也是handshaker,这里叫做WebSocketClientHandshaker。这个类有什么作用呢?一起来看看。
这个类主要实现的就是client和server端之间的握手。
我们看一下它的最长参数的构造类:
protectedWebSocketClientHandshaker(URIuri,WebSocketVersionversion,Stringsubprotocol,HttpHeaderscustomHeaders,intmaxFramePayloadLength,longforceCloseTimeoutMillis,booleanabsoluteUpgradeUrl)
参数中有websocket连接的URI,像是:"ws://flydean.com/mypath"。
有请求子协议的类型subprotocol,有自定义的HTTPheaders:customHeaders,有最大的framepayload的长度:maxFramePayloadLength,有强制timeout关闭的时间,有使用HTTP协议进行升级的URI地址。
怎么创建handshaker呢?同样的,netty提供了一个WebSocketClientHandshakerFactory方法。
WebSocketClientHandshakerFactory提供了一个newHandshaker方法,可以方便的创建各种不同版本的handshaker:
if(version==V13){returnnewWebSocketClientHandshaker13(webSocketURL,V13,subprotocol,allowExtensions,customHeaders,maxFramePayloadLength,performMasking,allowMaskMismatch,forceCloseTimeoutMillis);}if(version==V08){returnnewWebSocketClientHandshaker08(webSocketURL,V08,subprotocol,allowExtensions,customHeaders,maxFramePayloadLength,performMasking,allowMaskMismatch,forceCloseTimeoutMillis);}if(version==V07){returnnewWebSocketClientHandshaker07(webSocketURL,V07,subprotocol,allowExtensions,customHeaders,maxFramePayloadLength,performMasking,allowMaskMismatch,forceCloseTimeoutMillis);}if(version==V00){returnnewWebSocketClientHandshaker00(webSocketURL,V00,subprotocol,customHeaders,maxFramePayloadLength,forceCloseTimeoutMillis);}
可以看到,根据传入协议版本的不同,可以分为WebSocketClientHandshaker13、WebSocketClientHandshaker08、WebSocketClientHandshaker07、WebSocketClientHandshaker00这几种。
WebSocketClientCompressionHandler
通常来说,对于webSocket协议,为了提升传输的性能和速度,降低网络带宽占用量,在使用过程中通常会带上额外的压缩扩展。为了处理这样的压缩扩展,netty同时提供了服务器端和客户端的支持。
对于服务器端来说对应的handler叫做WebSocketServerCompressionHandler,对于客户端来说对应的handler叫做WebSocketClientCompressionHandler。
通过将这两个handler加入对应pipline中,可以实现对websocket中压缩协议扩展的支持。
对于协议的扩展有两个级别分别是permessage-deflate和perframe-deflate,分别对应PerMessageDeflateClientExtensionHandshaker和DeflateFrameClientExtensionHandshaker。
至于具体怎么压缩的,这里就不详细进行讲解了,感兴趣的小伙伴可以自行了解。
netty客户端的处理流程
前面讲解了netty对websocket客户端的支持之后,本节将会讲解netty到底是如何使用这些工具进行消息处理的。
首先是按照正常的逻辑创建客户端的Bootstrap,并添加handler。这里的handler就是专门为websocket定制的client端handler。
除了上面提到的WebSocketClientCompressionHandler,就是自定义的handler了。
在自定义handler中,我们需要处理两件事情,一件事情就是在channelready的时候创建handshaker。另外一件事情就是具体websocket消息的处理了。
创建handshaker
首先使用WebSocketClientHandshakerFactory创建handler:
TestSocketClientHandlerhandler=newTestSocketClientHandler(WebSocketClientHandshakerFactory.newHandshaker(uri,WebSocketVersion.V13,null,true,newDefaultHttpHeaders()));
然后在channelactive的时候使用handshaker进行握手连接:
publicvoidchannelActive(ChannelHandlerContextctx){handshaker.handshake(ctx.channel());}
然后在进行消息接收处理的时候还需要判断handshaker的状态是否完成,如果未完成则调用handshaker.finishHandshake方法进行手动完成:
if(!handshaker.isHandshakeComplete()){try{handshaker.finishHandshake(ch,(FullHttpResponse)msg);log.info("websocketHandshake完成!");handshakeFuture.setSuccess();}catch(WebSocketHandshakeExceptione){log.info("websocket连接失败!");handshakeFuture.setFailure(e);}return;}
当handshake完成之后,就可以进行正常的websocket消息读写操作了。
websocket消息的处理
websocket的消息处理比较简单,将接收到的消息转换成为WebSocketFrame进行处理即可。
WebSocketFrameframe=(WebSocketFrame)msg;if(frameinstanceofTextWebSocketFrame){TextWebSocketFrametextFrame=(TextWebSocketFrame)frame;log.info("接收到TXT消息:"+textFrame.text());}elseif(frameinstanceofPongWebSocketFrame){log.info("接收到pong消息");}elseif(frameinstanceofCloseWebSocketFrame){log.info("接收到closing消息");ch.close();}总结
本文讲解了netty提供的websocket客户端的支持和具体的对接流程,大家可以再次基础上进行扩展,以实现自己的业务逻辑。
本文的例子可以参考:learn-netty4
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!