线程化TCP服务器作为连接用户与Unix套接字之间的代理

0 投票
3 回答
2200 浏览
提问于 2025-04-15 11:26

我正在写一个网页应用,需要把数据从服务器推送到连接的用户。这些数据可以来自网页应用中的任何其他脚本。例如,当一个用户在服务器上做了一些更改,其他用户就应该收到通知。

所以我的想法是使用 Unix 套接字(套接字的路径是基于用户的 ID)来发送数据给对应的用户(网页应用的脚本会连接到这个套接字并写入数据)。第二部分是 ThreadingTCPServer,它会接受用户的连接,并通过 TCP 套接字连接把数据从 Unix 套接字推送给用户。

这里是工作流程:

  1. 用户连接到 TCP 服务器
  2. Django 脚本打开 Unix 套接字并向其写入数据。
  3. TCP 服务器从 Unix 套接字读取数据,并将其发送给与用户的开放连接。

我希望你能理解我的想法 :)

所以,我有两个问题:

1. 你觉得我的想法总体上怎么样?是个好主意还是坏主意?欢迎任何建议。

2. 这是我的代码。

import SocketServer
import socket
import netstring
import sys, os, os.path
import string
import time

class MyRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        try:
            print "Connected:", self.client_address

            user = self.request.recv(1024).strip().split(":")[1]
            user = int(user)
            self.request.send('Welcome #%s' % user)

            self.usocket_path = '/tmp/u%s.sock' % user
            if os.path.exists(self.usocket_path):
                os.remove(self.usocket_path)

            self.usocket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
            self.usocket.bind(self.usocket_path)
            self.usocket.listen(1)

            while 1:
                usocket_conn, addr = self.usocket.accept()
                while 1:
                    data = usocket_conn.recv(1024)
                    if not data: break
                    self.request.send(data)
                    break
                usocket_conn.close()
                time.sleep(0.1)

        except KeyboardInterrupt:
            self.request.send('close')
            self.request.close()

myServer = SocketServer.ThreadingTCPServer(('', 8081), MyRequestHandler)
myServer.serve_forever()

然后我遇到了一个异常

  File "server1.py", line 23, in handle
    self.usocket.listen(1)
  File "<string>", line 1, in listen
error: (102, 'Operation not supported on socket')

3 个回答

0

你应该使用Twisted,或者更具体一点,使用Orbited,来把数据推送给你的客户端。你发的示例代码有很多潜在的问题,找出这些问题会比直接使用一个现成的代码要困难得多,这样你就可以轻松实现你想要的功能。

0

这太复杂了。请使用socketserver模块。

1

我觉得你不应该使用Unix套接字。如果你的应用将来变得受欢迎或者非常重要,你就不能简单地添加一个服务器来提高性能或者确保系统的可靠性。

相反,如果你把数据放到比如memcached里(并把用户的“数据集编号”作为单独的键),那么你就可以从多个服务器存储数据,也可以从多个服务器读取数据。如果用户断开连接后又从其他服务器重新连接,你仍然可以为他获取数据。

你也可以使用数据库(这样更能确保系统的可靠性),或者如果你愿意,可以结合使用数据库和memcached。不过我见过一个应用使用Unix套接字的方式,后来那个程序员对此感到后悔。你可以设置一个表格,里面有用户ID、数据和时间戳的列,这样你就可以记住某个用户的最后时间戳。

撰写回答