You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tornado WebSocket出现1006关闭码,由connection.finish触发,求代码问题排查

问题修复方案

WebSocket 1006错误码代表连接异常中断,未收到正常的关闭控制帧,你的Demo有两个核心错误直接导致该问题:

1. 端口配置不匹配

你的服务端通过app.listen(8889)监听的是8889端口,但客户端连接地址写的是ws://localhost:9998/ws,端口完全不一致,客户端无法和对应服务建立连接,直接触发异常断开。
修复方案:将两端端口改为统一值即可,比如把客户端连接地址改为ws://localhost:8889/ws。

2. 服务端on_close方法存在属性未定义异常

你在on_close回调中调用了self.loop.stop(),但ConnectHandler类全程没有定义loop属性,连接关闭触发该方法时会直接抛出AttributeError,Tornado遇到未捕获的业务异常会主动中断WebSocket连接,触发1006关闭码。
修复方案:

  • 如果不需要在连接关闭时停止全局事件循环,直接删除self.loop.stop()这行代码即可;
  • 如果确实有停止事件循环的需求,在simple_init方法中补充定义loop属性:self.loop = tornado.ioloop.IOLoop.current()。

修复后可运行代码示例

服务端代码

import tornado.ioloop
import tornado.web
import tornado.websocket
import time


class ConnectHandler(tornado.websocket.WebSocketHandler):
    def simple_init(self):
        self.last = time.time()
        self.stop = False
        # 若需要停止事件循环则加下面这行
        # self.loop = tornado.ioloop.IOLoop.current()

    def check_origin(self, origin):
        return True

    def open(self):
        self.simple_init()
        print("New client connecting")
        self.write_message('Welcome')
        print("New client connected")

    def on_close(self):
        print("connection is closed")
        # 已删除不存在的self.loop.stop()调用
        # 如果需要停止事件循环,保留下面这行
        # self.loop.stop()

    def on_message(self, message):
        self.write_message('new message :' + message)


class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r'/ws', ConnectHandler)
        ]
        super().__init__(handlers)


if __name__ == "__main__":
    app = Application()
    app.listen(8889)
    tornado.ioloop.IOLoop.current().start()

客户端代码

from websocket import create_connection


def short_lived_connection():
    # 端口改为和服务端一致的8889
    ws = create_connection("ws://localhost:8889/ws")
    print("send hello server")
    ws.send("hello, server")
    print("sent")
    print("receiving...")
    # 第一次接收连接建立时推送的Welcome消息
    result = ws.recv()
    print("Received '%s'" % result)
    # 第二次接收服务端对客户端消息的回复
    result = ws.recv()
    print("Received '%s'" % result)
    ws.close()


if __name__ == '__main__':
    short_lived_connection()

注:客户端需要调用两次recv,因为服务端在连接open时会先推送一次Welcome消息,收到客户端消息后又会推送一次回复,只调用一次recv会导致第二次消息未接收就关闭连接,也可能触发异常。


内容的提问来源于stack exchange,提问作者yinsen cai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 20:39:03