线程化TCP服务器作为连接用户与Unix套接字之间的代理
我正在写一个网页应用,需要把数据从服务器推送到连接的用户。这些数据可以来自网页应用中的任何其他脚本。例如,当一个用户在服务器上做了一些更改,其他用户就应该收到通知。
所以我的想法是使用 Unix 套接字(套接字的路径是基于用户的 ID)来发送数据给对应的用户(网页应用的脚本会连接到这个套接字并写入数据)。第二部分是 ThreadingTCPServer,它会接受用户的连接,并通过 TCP 套接字连接把数据从 Unix 套接字推送给用户。
这里是工作流程:
- 用户连接到 TCP 服务器
- Django 脚本打开 Unix 套接字并向其写入数据。
- 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、数据和时间戳的列,这样你就可以记住某个用户的最后时间戳。