ink*_*min 3 lisp common-lisp websocket usocket
我正在尝试升级协议,从HTTP 1.1切换到WebSockets.我试过用usocket.到目前为止我的代码如下(并作为GitHub要点提供).握手读取后,函数返回NIL或unexpected 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))
Run Code Online (Sandbox Code Playgroud)
~%在FORMAT语句中,为了HTTP协议,它是不可移植的.它输出换行符#\newline.换行取决于代码运行的平台:cr(旧Mac,Lisp机器),crlf(Windows)或lf(Unix).因此,如果您将一个换行符写入流,则输出取决于您运行的平台(或Lisp系统认为应该执行的操作).Windows具有与HTTP相同的行结束约定.
注意:
#\newline是一样的#\linefeed.单个字符.#\newline与序列相同#\return #\linefeed.两个字符.一些Lisp系统可能会忽略它并使用Unix约定.HTTP使用crlf.为了可靠地编写crlf,你必须编写字符#\return和#\linefeed:(format stream "~a~a" #\return #\linefeed).
(defun write-crlf (stream)
(write-char #\return stream)
(write-char #\linefeed stream))
Run Code Online (Sandbox Code Playgroud)
但是,有些服务器可能非常愚蠢,无法读取不符合标准HTTP crlf约定的输入.
打开流时,可能有方法指定行结束约定.usocket但是,它没有提供这样的功能.
我也会使用finish-output(等待完成)而不是force-output(不等待IO操作完成).
| 归档时间: |
|
| 查看次数: |
701 次 |
| 最近记录: |