gpt4 book ai didi

带有 usocket 库的 Common Lisp 中的 WebSocket 客户端

转载 作者:太空宇宙 更新时间:2023-11-03 18:41:35 26 4
gpt4 key购买 nike

我正在尝试升级协议(protocol),从 HTTP 1.1 切换到 WebSockets。我试过使用 usocket .到目前为止我的代码如下(并且可以作为 GitHub gist 获得)。握手读取后,函数返回 NILunexpected EOF 错误。

;; Define parameter sock for usocket stream
;; echo.websocket.org is a site for testing websockets
(defparameter sock (usocket:socket-connect "echo.websocket.org" 80))

;; Output confirms WebSocket protocol handshake as this implemented in browsers
(format (usocket:socket-stream sock) "~A~%~A~%~A~%~A~%~A~A~%~A~%~A~%~%"
"GET /?encoding=text HTTP/1.1"
"Connection: Upgrade"
"Host: echo.websocket.org"
"Origin: http://www.websocket.org"
"Sec-WebSocket-Key: " (generate-websocket-key)
"Sec-WebSocket-Version: 13"
"Upgrade: websocket")

;; Write output to stream
(force-output (usocket:socket-stream sock))

;; Returns NIL
(do ((line
(read-line (usocket:socket-stream sock) nil)
(read-line (usocket:socket-stream sock) nil)))
((not line))
(format t "~A" line))

;; Returns error: unexpected EOF
(read-line (usocket:socket-stream sock))

;; Returns NIL
(listen (usocket:socket-stream sock))

最佳答案

出于 HTTP 协议(protocol)的目的,FORMAT 语句中的

~% 不可移植。它输出换行符 #\newline。换行符取决于代码运行的平台:cr(旧 Mac、Lisp 机器)、crlf(Windows)或 lf(Unix)。因此,如果您将换行符写入流,输出取决于您运行的平台(或 Lisp 系统认为它应该做什么)。 Windows 具有与 HTTP 相同的行结束约定。

注意:

  • 在 Unix 系统上,通常 #\newline#\linefeed 相同。单个字符。
  • 在 Windows 系统上,#\newline 通常与序列 #\return #\linefeed 相同。两个字符。一些 Lisp 系统可能会忽略这一点并使用 Unix 约定。

HTTP 使用 crlf。要可靠地编写 crlf,您必须编写字符 #\return#\linefeed: (format stream "~a~a"#\return #\换行)

(defun write-crlf (stream)
(write-char #\return stream)
(write-char #\linefeed stream))

不过,有些服务器可能不够笨,无法读取不遵循标准 HTTP crlf 约定的输入。

打开流时,可能有一些方法可以指定行结束约定。 usocket 不提供这样的功能。

我还会使用 finish-output(等待完成)而不是 force-output(不等待 IO 操作完成)。

关于带有 usocket 库的 Common Lisp 中的 WebSocket 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25608424/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com