Потоковая передача TCP-сервера в качестве прокси между подключенным пользователем и сокетом unix - PullRequest
0 голосов
/ 07 мая 2009

Я пишу веб-приложение, в котором мне нужно отправить данные с сервера на подключенные клиенты. Эти данные можно отправить из любого другого скрипта из веб-приложения. Например, один пользователь вносит некоторые изменения на сервере, а другие пользователи должны быть уведомлены об этом.

Так что моя идея заключается в том, чтобы использовать сокет unix (путь к сокету на основе идентификатора пользователя #) для отправки данных для соответствующего пользователя (сценарии веб-приложения будут подключаться к этому сокету и записывать данные). Вторая часть - это ThreadingTCPServer, который будет принимать пользовательские соединения и передавать данные из сокета unix пользователю через соединение через сокет TCP.

Вот рабочий процесс:

  1. Используется подключение к TCP-серверу
  2. Скрипт Django открывает unixsocket и записывает в него данные.
  3. TCP-сервер считывает данные из сокета unix и отправляет их для открытия соединения с пользователем.

Надеюсь, вы понимаете мою идею:)

Итак, у меня есть 2 вопроса:

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 ]

1 голос
/ 07 мая 2009

Я думаю, вам не следует использовать unix-сокеты. Если ваше приложение (когда-нибудь) станет популярным или критически важным, вы не сможете просто добавить другой сервер, чтобы добавить масштабируемость или сделать его избыточным и отказоустойчивым.

Если, с другой стороны, Вы поместите данные в т. Е. memcached (и "номер набора данных" пользователя в качестве отдельного ключа) Вы сможете помещать данные в memcached с нескольких серверов и читать их с нескольких серверов. Если пользователь отключится и подключится к другому серверу, вы все равно сможете получить данные для него.

Вы также можете использовать базу данных (чтобы сделать ее более отказоустойчивой) или смесь базы данных и memcached, если хотите, но я видел приложение, использующее сокеты unix, как вы пытаетесь, и программиста. пожалел об этом позже. В таблице могут быть столбцы идентификаторов пользователей, данных и отметок времени, и вы можете запомнить последнюю отметку времени для данного пользователя.

0 голосов
/ 17 июня 2009

Вы должны использовать Twisted или, более конкретно, Orbited , чтобы передавать данные своим клиентам. Пример кода, который вы разместили, имеет ряд потенциальных проблем, и было бы намного сложнее выяснить, что они все из себя представляют, чем вам просто использовать предварительно созданный кусок кода, чтобы делать то, что вам нужно.

0 голосов
/ 07 мая 2009

Это слишком сложно. Используйте модуль socketserver , пожалуйста.

...