検索

ホームページ  >  に質問  >  本文

node.js - 为什么 Socket.IO 可以让 WebSockets 和 HTTP 监听在同一端口?

按 TCP 或者 HTTP, 两个服务监听同一端口是会报错的,
但 Socket.IO 却可以直接监听 Express 服务器的同一端口,
具体原因是什么?

WebSockets 是基于 HTTP 实现, 是否相关?

高洛峰高洛峰2779日前722

全員に返信(3)返信します

  • 怪我咯

    怪我咯2017-04-17 11:08:14

    应该是两个程序监听一个端口会报错。

    websocket, http 都是基于tcp实现的。websocket 的连接请求都是用的http。websocket和http是在一个层面上的东西。比如在Go中处理websocket请求:

    路由:

    http.HandleFunc("/ws", serveWs)
    

    处理action:

    func serveWs(w http.ResponseWriter, r *http.Request) {
        if r.Method != "GET" {
            http.Error(w, "Method not allowed", 405)
            return
        }
        if r.Header.Get("Origin") != "http://"+r.Host {
            http.Error(w, "Origin not allowed", 403)
            return
        }
        ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
        if _, ok := err.(websocket.HandshakeError); ok {
            http.Error(w, "Not a websocket handshake", 400)
            return
        } else if err != nil {
            log.Println(err)
            return
        }
        c := &connection{send: make(chan []byte, 256), ws: ws}
        h.register <- c
        c.writePump()
        h.unregister <- c
    }
    

    和普通的http请求处理很类似,也是使用GET方法,Node的原理也是一样的。

    另外一个端口可以接受多个tcp请求。

    返事
    0
  • 大家讲道理

    大家讲道理2017-04-17 11:08:14

    因为 WebSocket 是基于 HTTP 1.1 的一个功能,它本身是依赖 HTTP 的(使用 101 状态码来切换协议)。Express 应该知道自己已经监听了那个端口,所以没有再尝试监听(bind(2)),而只是给那个端口来的请求注册了针对 HTTP WebSocket 请求的处理方法。

    返事
    0
  • PHP中文网

    PHP中文网2017-04-17 11:08:14

    按理说TCP与HTTP之间是不能用「或者」的。
    在OSI模型中,TCP是第四层传输层的协议,HTTP是第七层应用层的协议。

    你的问题可以这样理解,socket.io 和 Express 都在使用node正在监听的端口来分别处理请求,而不是分别监听端口。

    返事
    0
  • キャンセル返事