-
此websocket网址“ ws:// {{$}} / ws”是什么意思?
2013-08-17 16:14:34<p>I work with websocket in go. And I got a websocket url format from a trivial example that I google like this: <pre><code>ws://{{$}}/ws </code></pre> <p>Relatively complete code below: <p>home.... -
线上环境websocket连接地址_WebSocket:沙盒里的TCP
2020-11-25 22:20:01在之前讲 TCP/IP 协议栈的时候,我...单从名字上看,“Web”指的是 HTTP,“Socket”是套接字调用,那么这两个连起来又是什么意思呢?所谓“望文生义”,大概你也能猜出来,“WebSocket”就是运行在“Web”,也就是...
在之前讲 TCP/IP 协议栈的时候,我说过有“TCP Socket”,它实际上是一种功能接口,通过这些接口就可以使用 TCP/IP 协议栈在传输层收发数据。
那么,你知道还有一种东西叫“WebSocket”吗?
单从名字上看,“Web”指的是 HTTP,“Socket”是套接字调用,那么这两个连起来又是什么意思呢?
所谓“望文生义”,大概你也能猜出来,“WebSocket”就是运行在“Web”,也就是 HTTP 上的 Socket 通信规范,提供与“TCP Socket”类似的功能,使用它就可以像“TCP Socket”一样调用下层协议栈,任意地收发数据。
更准确地说,“WebSocket”是一种基于 TCP 的轻量级网络通信协议,在地位上是与 HTTP“平级”的。
为什么要有 WebSocket
不过,已经有了被广泛应用的 HTTP 协议,为什么要再出一个 WebSocket 呢?它有哪些好处呢?
其实 WebSocket 与 HTTP/2 一样,都是为了解决 HTTP 某方面的缺陷而诞生的。HTTP/2 针对的是“队头阻塞”,而 WebSocket 针对的是“请求 - 应答”通信模式。
那么,“请求 - 应答”有什么不好的地方呢?
“请求 - 应答”是一种“半双工”的通信模式,虽然可以双向收发数据,但同一时刻只能一个方向上有动作,传输效率低。更关键的一点,它是一种“被动”通信模式,服务器只能“被动”响应客户端的请求,无法主动向客户端发送数据。
虽然后来的 HTTP/2、HTTP/3 新增了 Stream、Server Push 等特性,但“请求 - 应答”依然是主要的工作方式。这就导致 HTTP 难以应用在动态页面、即时消息、网络游戏等要求“实时通信”的领域。
在 WebSocket 出现之前,在浏览器环境里用 JavaScript 开发实时 Web 应用很麻烦。因为浏览器是一个“受限的沙盒”,不能用 TCP,只有 HTTP 协议可用,所以就出现了很多“变通”的技术,“轮询”(polling)就是比较常用的的一种。
简单地说,轮询就是不停地向服务器发送 HTTP 请求,问有没有数据,有数据的话服务器就用响应报文回应。如果轮询的频率比较高,那么就可以近似地实现“实时通信”的效果。
但轮询的缺点也很明显,反复发送无效查询请求耗费了大量的带宽和 CPU 资源,非常不经济。
所以,为了克服 HTTP“请求 - 应答”模式的缺点,WebSocket 就“应运而生”了。它原来是 HTML5 的一部分,后来“自立门户”,形成了一个单独的标准,RFC 文档编号是 6455。
WebSocket 的特点
WebSocket 是一个真正“全双工”的通信协议,与 TCP 一样,客户端和服务器都可以随时向对方发送数据,而不用像 HTTP“你拍一,我拍一”那么“客套”。于是,服务器就可以变得更加“主动”了。一旦后台有新的数据,就可以立即“推送”给客户端,不需要客户端轮询,“实时通信”的效率也就提高了。
WebSocket 采用了二进制帧结构,语法、语义与 HTTP 完全不兼容,但因为它的主要运行环境是浏览器,为了便于推广和应用,就不得不“搭便车”,在使用习惯上尽量向 HTTP 靠拢,这就是它名字里“Web”的含义。
服务发现方面,WebSocket 没有使用 TCP 的“IP 地址 + 端口号”,而是延用了 HTTP 的 URI 格式,但开头的协议名不是“http”,引入的是两个新的名字:“ws”和“wss”,分别表示明文和加密的 WebSocket 协议。
WebSocket 的默认端口也选择了 80 和 443,因为现在互联网上的防火墙屏蔽了绝大多数的端口,只对 HTTP 的 80、443 端口“放行”,所以 WebSocket 就可以“伪装”成 HTTP 协议,比较容易地“穿透”防火墙,与服务器建立连接。具体是怎么“伪装”的,我稍后再讲。
下面我举几个 WebSocket 服务的例子,你看看,是不是和 HTTP 几乎一模一样:
ws://www.chrono.comws://http://www.chrono.com:8080/srvwss://www.chrono.com:445/im?user_id=xxx复制代码
要注意的一点是,WebSocket 的名字容易让人产生误解,虽然大多数情况下我们会在浏览器里调用 API 来使用 WebSocket,但它不是一个“调用接口的集合”,而是一个通信协议,所以我觉得把它理解成“TCP over Web”会更恰当一些。
WebSocket 的帧结构
刚才说了,WebSocket 用的也是二进制帧,有之前 HTTP/2、HTTP/3 的经验,相信你这次也能很快掌握 WebSocket 的报文结构。
不过 WebSocket 和 HTTP/2 的关注点不同,WebSocket 更侧重于“实时通信”,而 HTTP/2 更侧重于提高传输效率,所以两者的帧结构也有很大的区别。
WebSocket 虽然有“帧”,但却没有像 HTTP/2 那样定义“流”,也就不存在“多路复用”“优先级”等复杂的特性,而它自身就是“全双工”的,也就不需要“服务器推送”。所以综合起来,WebSocket 的帧学习起来会简单一些。
下图就是 WebSocket 的帧结构定义,长度不固定,最少 2 个字节,最多 14 字节,看着好像很复杂,实际非常简单。
开头的两个字节是必须的,也是最关键的。
第一个字节的第一位“FIN”是消息结束的标志位,相当于 HTTP/2 里的“END_STREAM”,表示数据发送完毕。一个消息可以拆成多个帧,接收方看到“FIN”后,就可以把前面的帧拼起来,组成完整的消息。
“FIN”后面的三个位是保留位,目前没有任何意义,但必须是 0。
第一个字节的后 4 位很重要,叫“Opcode”,操作码,其实就是帧类型,比如 1 表示帧内容是纯文本,2 表示帧内容是二进制数据,8 是关闭连接,9 和 10 分别是连接保活的 PING 和 PONG。
第二个字节第一位是掩码标志位“MASK”,表示帧内容是否使用异或操作(xor)做简单的加密。目前的 WebSocket 标准规定,客户端发送数据必须使用掩码,而服务器发送则必须不使用掩码。
第二个字节后 7 位是“Payload len”,表示帧内容的长度。它是另一种变长编码,最少 7 位,最多是 7+64 位,也就是额外增加 8 个字节,所以一个 WebSocket 帧最大是 2^64。
长度字段后面是“Masking-key”,掩码密钥,它是由上面的标志位“MASK”决定的,如果使用掩码就是 4 个字节的随机数,否则就不存在。
这么分析下来,其实 WebSocket 的帧头就四个部分:“结束标志位 + 操作码 + 帧长度 + 掩码”,只是使用了变长编码的“小花招”,不像 HTTP/2 定长报文头那么简单明了。
我们的实验环境利用 OpenResty 的“lua-resty-websocket”库,实现了一个简单的 WebSocket 通信,你可以访问 URI“/38-1”,它会连接后端的 WebSocket 服务“ws://127.0.0.1/38-0”,用 Wireshark 抓包就可以看到 WebSocket 的整个通信过程。
下面的截图是其中的一个文本帧,因为它是客户端发出的,所以需要掩码,报文头就在两个字节之外多了四个字节的“Masking-key”,总共是 6 个字节。
而报文内容经过掩码,不是直接可见的明文,但掩码的安全强度几乎是零,用“Masking-key”简单地异或一下就可以转换出明文。
WebSocket 的握手
和 TCP、TLS 一样,WebSocket 也要有一个握手过程,然后才能正式收发数据。
这里它还是搭上了 HTTP 的“便车”,利用了 HTTP 本身的“协议升级”特性,“伪装”成 HTTP,这样就能绕过浏览器沙盒、网络防火墙等等限制,这也是 WebSocket 与 HTTP 的另一个重要关联点。
WebSocket 的握手是一个标准的 HTTP GET 请求,但要带上两个协议升级的专用头字段:- “Connection: Upgrade”,表示要求协议“升级”;
- “Upgrade: websocket”,表示要“升级”成 WebSocket 协议。
另外,为了防止普通的 HTTP 消息被“意外”识别成 WebSocket,握手消息还增加了两个额外的认证用头字段(所谓的“挑战”,Challenge):
- Sec-WebSocket-Key:一个 Base64 编码的 16 字节随机数,作为简单的认证密钥;
- Sec-WebSocket-Version:协议的版本号,当前必须是 13。
服务器收到 HTTP 请求报文,看到上面的四个字段,就知道这不是一个普通的 GET 请求,而是 WebSocket 的升级请求,于是就不走普通的 HTTP 处理流程,而是构造一个特殊的“101 Switching Protocols”响应报文,通知客户端,接下来就不用 HTTP 了,全改用 WebSocket 协议通信。(有点像 TLS 的“Change Cipher Spec”)
WebSocket 的握手响应报文也是有特殊格式的,要用字段“Sec-WebSocket-Accept”验证客户端请求报文,同样也是为了防止误连接。
具体的做法是把请求头里“Sec-WebSocket-Key”的值,加上一个专用的 UUID “258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,再计算 SHA-1 摘要。
encode_base64( sha1( Sec-WebSocket-Key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' ))复制代码
客户端收到响应报文,就可以用同样的算法,比对值是否相等,如果相等,就说明返回的报文确实是刚才握手时连接的服务器,认证成功。
握手完成,后续传输的数据就不再是 HTTP 报文,而是 WebSocket 格式的二进制帧了。
小结
浏览器是一个“沙盒”环境,有很多的限制,不允许建立 TCP 连接收发数据,而有了 WebSocket,我们就可以在浏览器里与服务器直接建立“TCP 连接”,获得更多的自由。
不过自由也是有代价的,WebSocket 虽然是在应用层,但使用方式却与“TCP Socket”差不多,过于“原始”,用户必须自己管理连接、缓存、状态,开发上比 HTTP 复杂的多,所以是否要在项目中引入 WebSocket 必须慎重考虑。- HTTP 的“请求 - 应答”模式不适合开发“实时通信”应用,效率低,难以实现动态页面,所以出现了 WebSocket;
- WebSocket 是一个“全双工”的通信协议,相当于对 TCP 做了一层“薄薄的包装”,让它运行在浏览器环境里;
- WebSocket 使用兼容 HTTP 的 URI 来发现服务,但定义了新的协议名“ws”和“wss”,端口号也沿用了 80 和 443;
- WebSocket 使用二进制帧,结构比较简单,特殊的地方是有个“掩码”操作,客户端发数据必须掩码,服务器则不用;
- WebSocket 利用 HTTP 协议实现连接握手,发送 GET 请求要求“协议升级”,握手过程中有个非常简单的认证机制,目的是防止误连接。
课下作业
- WebSocket 与 HTTP/2 有很多相似点,比如都可以从 HTTP/1 升级,都采用二进制帧结构,你能比较一下这两个协议吗?
- 试着自己解释一下 WebSocket 里的”Web“和”Socket“的含义。
- 结合自己的实际工作,你觉得 WebSocket 适合用在哪些场景里?
欢迎你把自己的学习体会写在留言区,与我和其他同学一起讨论。如果你觉得有所收获,也欢迎把文章分享给你的朋友。
-
websocket连接成功建立以后前台的onmessage不会自动触发,为什么?
2019-03-13 14:37:56如题,websocket已经成功连接,readystate状态码是1(已建立连接可通讯的意思),后台向前台推送的数据其实是可以接收到的,但是只能靠我手动刷新页面,他才会调用一次onmessage回调方法,没有办法实时接收到数据,... -
Golang websocket.Conn的再封装
2020-11-17 20:57:02我们知道我们可以直接用websocket.Conn进行ws通讯,可是为什么要对他进行二次封装,主要有两个原因。 1,不方便分模块调用 2,websocket.Conn中的很多方法是非线程安全的 线程安全的意思是当多线程调用同一模块时,...我们知道我们可以直接用websocket.Conn进行ws通讯,可是为什么要对他进行二次封装,主要有两个原因。
1,不方便分模块调用
2,websocket.Conn中的很多方法是非线程安全的
线程安全的意思是当多线程调用同一模块时,相对安全的不会出错。
js对ws的简单封装
首先我们稍微优化一下测试前端。
如果不对WebSocket对象封装的话,我们无法手动控制连接的状态。
<!doctype html> <html> <head> <meta charset="utf-8"/> <title>WebSocket</title> </head> <body> <button type="button" onclick="connnectWS()">建立连接</button> <button type="button" onclick="sendMeg()">发送消息</button> <button type="button" onclick="connClose()">关闭连接</button> <div id="content"></div> <script> var text=document.getElementById("content"); var link="ws://localhost:6060/ws"; var conn={ connect:function(link) { this.ws=new WebSocket(link); //连接打开时触发 this.ws.onopen = function(evt) { console.log("Connection open ..."); }; //接收到消息时触发 this.ws.onmessage = function(evt) { text.innerHTML=text.innerHTML+"<br />"+evt.data; }; //连接关闭时触发 this.ws.onclose = function(evt) { console.log("Connection closed."); }; } } function connnectWS(){ conn.connect(link); } function sendMeg(){ conn.ws.send("Hello WebSocket!"); } function connClose(){ conn.ws.close(); } </script> </body> </html>
Go对ws的简单封装
我们先看看封装结构,之后我们在一个一个看方法。
type Connection struct { wsConn *websocket.Conn //websocket.Conn对象 inChan chan []byte //用于接收消息 outChan chan []byte //用于发送消息 closeChan chan byte //帮助内部逻辑判断连接是否被中断 mutex sync.Mutex //用于加锁 isClose bool //用于避免重复关闭中的不安全因素 }
下面是“构造方法”
const ( MAXMEGNUM = 1000 //最大消息数 ) //NewWS 构造一个WSConn func NewWS(wsConn *websocket.Conn) (conn *Connection, err error) { conn = &Connection{ wsConn: wsConn, inChan: make(chan []byte, MAXMEGNUM), outChan: make(chan []byte, MAXMEGNUM), closeChan: make(chan byte, 1), } go conn.readLoop() //执行内部读逻辑 go conn.writeLoop() //执行内部写逻辑 return }
读取和写单条消息的逻辑
//ReadMessage 读取一条消息,即接收 func (conn *Connection) ReadMessage() (data []byte, err error) { select { case data = <-conn.inChan: case <-conn.closeChan: err = errors.New("连接已关闭。") } return } //WriteMessage 写一条消息,即发送 func (conn *Connection) WriteMessage(data []byte) (err error) { select { case conn.outChan <- data: case <-conn.closeChan: err = errors.New("连接已关闭。") } return }
关闭连接的方法
func (conn *Connection) Close() { conn.wsConn.Close() //这个方法是线程安全的 conn.mutex.Lock() //上锁 //对Chan进行处理,并标记连接已关闭 if conn.isClose { close(conn.closeChan) conn.isClose = true } conn.mutex.Unlock() //解锁 }
内部实现的读写方法。避免死循环,我们使用select语句监听连接状态!
func (conn *Connection) readLoop() { for { megType, data, err := conn.wsConn.ReadMessage() //TODO 消息类型处理 megType = megType if err != nil { util.ErrHandle(err) conn.Close() return } select { case conn.inChan <- data: case <-conn.closeChan: conn.Close() return } } } func (conn *Connection) writeLoop() { var data []byte for { select { case data = <-conn.outChan: case <-conn.closeChan: conn.Close() return } //TODO 消息类型处理 err := conn.wsConn.WriteMessage(websocket.TextMessage, data) if err != nil { util.ErrHandle(err) conn.Close() return } } }
这样我们就封装了一个相对安全的ws封装,发现内容太多,就不掩饰了。下面给一个测试代码,有兴趣的朋友可以自己试一下。
func main() { r := gin.Default() r.GET("/ws", func(c *gin.Context) { upgrader := websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }} wsConn, err := upgrader.Upgrade(c.Writer, c.Request, nil) defer wsConn.Close() if err != nil { fmt.Println(err) return } conn, err := impl.NewWS(wsConn) defer conn.Close() if err != nil { fmt.Println(err) return } go func() { for { err := conn.WriteMessage([]byte("heartbeat")) if err != nil { fmt.Println(err) return } time.Sleep(time.Second * 3) } }() for { data, err := conn.ReadMessage() if err != nil { fmt.Println(err) return } err = conn.WriteMessage(data) if err != nil { fmt.Println(err) return } } }) r.Run(":6060") }
-
有几个websocket编程过程中的问题
2018-08-08 03:35:20新手入门,很多不知的@ServerEndpoint(value = "/websocket/{equipmentId}")和@GetMapping("gaming/{gameId}")很想知道,这两句代码分别代表什么意思 -
ie8-ie11浏览器是什么意思_h5是什么东西?可以用来做什么
2021-01-11 21:50:27一、HTML5中WebSocket是什么意思WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议,WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。...一、HTML5中WebSocket是什么意思
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议,WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。
以下 API 用于创建 WebSocket 对象。
var Socket = new WebSocket(url, [protocol] );
WebSocket 属性
二、Websocket是什么样的协议,具体有什么优点
首先,Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说。
简单的举个例子吧,用目前应用比较广泛的PHP生命周期来解释。
1) HTTP的生命周期通过Request来界定,也就是一个Request 一个Response,那么在HTTP1.0中,这次HTTP请求就结束了。
在HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response。
但是请记住 Request = Response , 在HTTP中永远是这样,也就是说一个request只能有一个response。而且这个response也是被动的,不能主动发起。
-
java websocket html5 启动服务器时抛出异常
2017-05-05 07:44:44javax.servlet.ServletException: javax.websocket.DeploymentException: Multiple Endpoints may not be deployed to the same path [/websocket] : ... 启动服务器时,信息中夹杂着这两个异常代码,什么意思呀? -
vue-cli本地的一个websocket
2020-08-14 09:35:15今天跑本地vue-cli项目,看到了一个websocket,如下图: 解惑如下: vue本质上还是编译成h5 就是说node相当于一个服务器 你执行npm run dev就是让node服务器编译vue 然后暴露端口 然后开了一个ws监听代码...今天跑本地vue-cli项目,看到了一个websocket,如下图:
解惑如下:
vue本质上还是编译成h5 就是说node相当于一个服务器 你执行npm run dev就是让node服务器编译vue 然后暴露端口 然后开了一个ws监听代码改动实时刷新 像vue的代理跨域啥的 你看为什么编译打包之后就没有了 就是因为代理是node搞得 你编译之后就只有单纯的h5代码 没有这个node了 编译之后也就是说其实随便丢到后端一个文件夹就可以访问了。是这个意思不
-
JavaScript调用浏览器里的websocket,如何多帧上行数据
2018-03-14 17:41:15JavaScript调用浏览器里的websocket,如何多个后续帧上行数据?这个组合帧的目的是什么?什么场景会用到?这个帧和http中的chunked编码有是不是一个意思?... -
websocket Could not decode a text frame as UTF-8
2016-12-02 04:03:37频率的话是用15个线程推送消息就基本上只能成功3-4条,然后浏览器就报错了,请问这个错误到底提示的是什么意思呢,有什么办法可以解决,现在我使用thread.sleep(1000),强制推送一条之后间隔1s再推送,感觉很low的... -
websocket SpringCloud Gateway onCloseWrapper code : 1009 reason:Max frame length of 65536
2020-04-03 17:46:29websocket客户端和服务端正常交互,但是发现会断开连接,不知道什么原因,客户端断开提示: WebsocketBase::onCloseWrapper code : 1009 reason:Max frame length of 65536 has bean exceeded. remote:true 大致意思... -
打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!
2018-07-17 17:23:55随着HTML5 WebSocket技术的日益成熟与普及,我们可以借助WebSocket来更加方便地打通BS与CS ... 我们可以尝试让Socket Server透明地支持WebSocket客户端,所谓透明的意思是,服务端开发人员不用关心客户端究竟是什么... -
Demo源码放送:打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!
2020-05-20 09:28:45我们可以尝试让Socket Server透明地支持WebSocket客户端,所谓透明的意思是,服务端开发人员不用关心客户端究竟是什么类型,而是可以统一的接收数据、处理数据、发送数据。为了做到这一点,我们可以构建一个服务端... -
WebsocketMessage 中 getPayload()的方法是什么意思
2017-11-14 09:40:51//接受消息,并发送出去 @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { Map, Object> attributes = ... 中 message.getPayload()表示什么意思 -
接口调用中提到的SDK是什么意思
2019-08-05 16:07:34查阅火币网API,有三种方式:ADK、API、Websocket API API (Application Programming Interface)=应用程序编程接口 SDK SDK (Software Development Kit)=软件开发工具包 可以简单理解为,SDK是将各种API再次... -
tomcat报这个错误是什么意思啊
2020-05-05 17:03:56org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) cn.itcauc.filter.GenericEncodingFilter.doFilter(GenericEncodingFilter.java:29) org.apache.struts2.dispatcher.ng.filter.... -
启动有个异常,是什么意思?不影响使用,能启动项目。
2017-11-09 06:48:57websocket服务器启动,端口8668 14:47:31.061 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Included patterns for restart : [] 14:47:31.063 [main] DEBUG org.springframework.... -
WebSocket: Establish full-duplex communication channels over a single TCP connection. Send and receive data Basic authentication using username and password Token based authentication Server Sent ...
-
【网络协议】为什么Socket要叫Socket
2020-01-02 09:58:42【socket】一词的本意即是【插座】的意思,我们日常编程中使用到WebSocket延用的便是【插座】这个本意 Socket大家都很常用,但是Socket到底是什么,为什么用【插座】一词来表示WebSocket,却很少有人能将明白 其实... -
为什么检索出来的list列表为空,或者来人教我别的查询方法吗。。
2016-08-30 05:10:00然后我把后面的删去,println那个p,是有值的,意思是下面那句话findAll出来的东西是空的,如果我什么都不输入,查询的结果就是整个数据库的第一行的那个id是可以的,但是无论我输入什么已有的name,都说我列表空的... -
Could not decode a text frame as UTF-8 的解决
2019-03-03 17:40:29Could not decode a text frame as UTF-8 的解决 ...很奇怪是什么意思,我明明发的是二进制数据啊,何来的text。。。。 又去网上找了一下websocket的一些介绍,发现一张图 websocket的消息是分片发送的,每... -
python面试题、web框架比较_python面试题四:Python web框架
2020-12-22 13:25:011谈谈你对http协议的...2谈谈你对websocket协议的认识。3什么是magic string ?...7django、flask、tornado框架的比较?8什么是wsgi?9简述MVC和MTV10谈谈你对restfull 规范的认识?11接口的幂等性是什么意思?12什么... -
nginx连接不上,不过握手已经显示成功了,后边一堆东西看不懂,原谅我是做c的。。。
2017-04-17 04:14:34192.168.0.23 - - [17/Apr/2017:11:33:55 +0800] "GET // HTTP/1.1" 200 612 "-" "-" 这个什么意思?我用http://www.blue-zero.com/WebSocket/网站连接的 -
wamp文件更新后服务内容不更新_Vite: 如何实现热更新
2020-12-08 19:43:17前言之前的一篇文章说了 Vite: 如何不使用 ...但首先我们需要知道「热更新」是什么意思,它跟直接刷新页面更新有什么不同的地方,实现的方式又有什么不同?下面的内容主要参考 前端工程化精讲[2]Live Reload我们... -
连夜撸了一个简易聊天室
2020-11-22 15:29:09点击上方Java后端,选择设为星标优质文章,及时送达分不清轮询、长轮询?不知道什么时候该用websocket还是SSE,看这篇就够了。所谓的“实时推送”,从表面意思上来看是,客户端订...
-
朱老师鸿蒙系列课程第1期-3.鸿蒙系统Harmonyos源码配置和管理
-
389.找不同
-
波卡向左,Cardano向右
-
PPT大神之路高清教程
-
零基础极简以太坊智能合约开发环境搭建并开发部署
-
50个微信小程序模板.zip
-
Galera 高可用 MySQL 集群(PXC v5.6 + Ngin
-
【考研初试】安徽农业大学849无机化学考研真题库资料
-
基于python的dango框架购物商城毕业设计毕设源代码使用教程
-
使用vue搭建微信H5公众号项目
-
华为1+X——网络系统建设与运维(高级)
-
LINUX下LM75B驱动
-
PTA团体程序设计天梯赛-练习集
-
边缘数据中心应用场景白皮书.pdf
-
项目经理成长之路
-
2021-03-02
-
智能停车场云平台(附vue+SpringBoot前后端项目源码)
-
localStorage 设置过期时间
-
Sybase ASE pcclient_1252 (ODBC DRIVER)
-
用微服务spring cloud架构打造物联网云平台