2011-01-21 17 views
43

Czy ktoś może polecić bibliotekę klienta Socket.IO dla języka Python? Rozejrzałem się, ale jedyne, co mogę znaleźć, to albo implementacja serwera, albo zależą od frameworka takiego jak Twisted.Biblioteka klientów Socket.IO w języku Python

Potrzebuję biblioteki klienta, która nie ma zależności od innych frameworków.

Po prostu użycie jednego z wielu typów połączeń nie jest wystarczające, ponieważ klient Pythona będzie musiał pracować z wieloma serwerami socketio, z których wiele nie obsługuje na przykład gniazd internetowych.

Odpowiedz

38

odpowiedź Archie1986 było dobre, ale stało się nieaktualne z socketio aktualizacjach (a dokładniej jego protokołem: https://github.com/LearnBoost/socket.io-spec) ... o ile mogę powiedzieć , musisz ręcznie wykonać uzgadnianie zanim będziesz mógł poprosić o połączenie transportowe (np. websockets) ... pamiętaj, że poniższy kod jest niepełny i niezabezpieczony ... dla jednego, ignoruje listę obsługiwanych transportów zwróconych w uzgadnianiu odpowiedź i zawsze stara się zdobyć websocket ... także zakłada, że ​​uzgadnianie zawsze kończy się sukcesem ...Niemniej jednak, jest to dobre miejsce do rozpoczęcia

import websocket, httplib 

... 

''' 
    connect to the socketio server 

    1. perform the HTTP handshake 
    2. open a websocket connection ''' 
def connect(self) : 
    conn = httplib.HTTPConnection('localhost:8124') 
    conn.request('POST','/socket.io/1/') 
    resp = conn.getresponse() 
    hskey = resp.read().split(':')[0] 

    self._ws = websocket.WebSocket(
        'ws://localhost:8124/socket.io/1/websocket/'+hskey, 
        onopen = self._onopen, 
        onmessage = self._onmessage) 

.... 

możesz również przeczytać na python-WebSocket: https://github.com/mtah/python-websocket

+3

To działa doskonale dla mnie. Dziękuję bardzo za zaktualizowaną odpowiedź! Chciałbym, żeby OP ponownie promował tę, ponieważ rzeczywista odpowiedź (jak zauważysz) nie będzie faktycznie działać z obecną specyfikacją. Wypełniłem resztę kodu dla prostego narzędzia wiersza poleceń, które działa ładnie. Może to być przydatne dla kogoś innego: https://gist.github.com/1402238 Zasadniczo jest to tylko kod z bardzo niewielkimi innymi rzeczami, które są w większości oczywiste, ale mam nadzieję, że to uratuje kogoś kiedyś. – drewww

3

Czy spojrzałeś na gevent-socketio?

Mam nadzieję, że to pomaga.

+9

gevent-socketio nie jest biblioteką klient Socket.IO dla Pythona ... to jest biblioteką serwer Socket.IO dla Pythona – Archie1986

+0

+1 To naprawdę mi pomógł, dzięki. –

24

Po pierwsze, nie jestem pewien, dlaczego niektóre serwery Socket.IO nie obsługują gniazd internetowych ... intencją Socket.IO jest ułatwienie tworzenia aplikacji WWW przez przeglądarkę front-end poprzez zapewnienie abstrakcyjny interfejs do strumieni danych w czasie rzeczywistym obsługiwanych przez serwer Socket.IO. Być może Socket.IO nie jest tym, czego powinieneś używać w swojej aplikacji? Poza tym, pozwól mi spróbować odpowiedzieć na twoje pytanie ...

W tym momencie nie ma żadnych bibliotek klienta Socket.IO dla Pythona (gevent-socketio nie jest biblioteką klienta Socket.IO dla Python ... jest to biblioteka Socket.IO serwera dla Pythona). Na razie będziesz musiał połączyć oryginalny kod w celu połączenia się z Socket.IO bezpośrednio jako klient, akceptując różne typy połączeń.

Wiem, że szukasz lekarstwa - wszystko to działa na różnych rodzajach połączeń (WebSocket, długie polling itd.), Ale ponieważ biblioteka taka jak ta jeszcze nie istnieje, mogę przynajmniej dać kilka wskazówek dotyczących korzystania z typu połączenia WebSocket na podstawie mojego doświadczenia.

Dla typu połączenia WebSocket utwórz klienta WebSocket w języku Python. Z wiersza poleceń zainstalować ten pakiet Python websocket Client here z pip tak, że jest na ścieżce Pythona tak:

pip install -e git+https://github.com/liris/websocket-client.git#egg=websocket

Gdy już to zrobisz spróbuj następujące, zastępując SOCKET_IO_HOST i SOCKET_IO_PORT z odpowiednim Lokalizacja serwera Socket.IO:

import websocket 

SOCKET_IO_HOST = "127.0.0.1" 
SOCKET_IO_PORT = 8080 

socket_io_url = 'ws://' + SOCKET_IO_HOST + ':' + str(SOCKET_IO_PORT) + '/socket.io/websocket' 

ws = websocket.create_connection(socket_io_url) 

w tym momencie masz medium łączenia z serwerem Socket.IO bezpośrednio z poziomu Pythona. Aby wysyłać wiadomości do serwera Socket.IO, wystarczy wysłać wiadomość przez to połączenie WebSocket. Aby serwer Socket.IO poprawnie interpretował przychodzące wiadomości za pośrednictwem tego WebSocket z klienta Python Socket.IO, musisz przestrzegać protokołu Socket.IO i kodować dowolne ciągi lub słowniki, które możesz wysłać przez połączenie WebSocket. Na przykład, po tym, jak osiągnąć wszystko powyżej należy wykonać następujące czynności:

def encode_for_socketio(message): 
    """ 
    Encode 'message' string or dictionary to be able 
    to be transported via a Python WebSocket client to 
    a Socket.IO server (which is capable of receiving 
    WebSocket communications). This method taken from 
    gevent-socketio. 
    """ 
    MSG_FRAME = "~m~" 
    HEARTBEAT_FRAME = "~h~" 
    JSON_FRAME = "~j~" 

    if isinstance(message, basestring): 
      encoded_msg = message 
    elif isinstance(message, (object, dict)): 
      return encode_for_socketio(JSON_FRAME + json.dumps(message)) 
    else: 
      raise ValueError("Can't encode message.") 

    return MSG_FRAME + str(len(encoded_msg)) + MSG_FRAME + encoded_msg 

msg = "Hello, world!" 
msg = encode_for_socketio(msg) 
ws.send(msg) 
+0

pełny przykład: http://pastebin.com/1Xt6X4K5 - ale tak naprawdę nie używam HTTP dokładnie, musiałem zmodyfikować websocket.py w ten sposób: http://pastebin.com/rh9WxxJA ponieważ, podejrzewam, że moja wersja urlparse nie rozpoznaje protokołu "ws: //". –

4

napisał jeden: https://github.com/amitu/amitu-websocket-client/blob/master/amitu/socketio_client.py. Obsługuje tylko websockets, więc może mieć tylko marginalną użyteczność dla ciebie.

+0

podczas wykonywania metody 'run()' pojawia się błąd: 'Niepoprawna ramka' - co to może oznaczać? – Alp

+0

Alp, to znaczy, że w bibliotece jest błąd. Zaktualizowałem go na podstawie ciągnięć od różnych współpracowników. Sprawdź najnowszą wersję i sprawdź, czy to pomaga. –

+0

Dziękuję za odpowiedź. W międzyczasie przełączyłem się na sockjs, który działa jak czar. Zobacz http://stackoverflow.com/questions/10950365/python-socket-io-client-for-sending-bcastcast-messages-to-tornadio2-server – Alp

5

SocketTornad.IO biblioteki z popularnym asynchronicznym Tornado Web Server jest również jedną z opcji dostępnych dla Pythona.

+2

lub nawet lepiej, bardziej aktualna wersja Tornadio2: https: // github.com/mrjoes/tornadIO2 --- ale są to biblioteki serwerów, nie przeznaczone do użytku jako klient. – Alp

20

Biblioteka socketIO-client obsługuje wywołania zwrotne zdarzeń i kanały dzięki pracy autorów i jest dostępna pod numerem PyPI w ramach licencji MIT.

Emituj z oddzwonieniem.

from socketIO_client import SocketIO 

def on_bbb_response(*args): 
    print 'on_bbb_response', args 

with SocketIO('localhost', 8000) as socketIO: 
    socketIO.emit('bbb', {'xxx': 'yyy'}, on_bbb_response) 
    socketIO.wait_for_callbacks(seconds=1) 

Definiowanie zdarzeń.

from socketIO_client import SocketIO 

def on_aaa_response(*args): 
    print 'on_aaa_response', args 

socketIO = SocketIO('localhost', 8000) 
socketIO.on('aaa_response', on_aaa_response) 
socketIO.emit('aaa') 
socketIO.wait(seconds=1) 

Definiowanie zdarzenia w przestrzeni nazw.

from socketIO_client import SocketIO, BaseNamespace 

class Namespace(BaseNamespace): 

    def on_aaa_response(self, *args): 
     print 'on_aaa_response', args 
     self.emit('bbb') 

socketIO = SocketIO('localhost', 8000) 
socketIO.define(Namespace) 
socketIO.emit('aaa') 
socketIO.wait(seconds=1) 

zdefiniowanie różnych nazw w jednym gnieździe.

from socketIO_client import SocketIO, BaseNamespace 

class ChatNamespace(BaseNamespace): 

    def on_aaa_response(self, *args): 
     print 'on_aaa_response', args 

class NewsNamespace(BaseNamespace): 

    def on_aaa_response(self, *args): 
     print 'on_aaa_response', args 

socketIO = SocketIO('localhost', 8000) 
chatNamespace = socketIO.define(ChatNamespace, '/chat') 
newsNamespace = socketIO.define(NewsNamespace, '/news') 

chatNamespace.emit('aaa') 
newsNamespace.emit('aaa') 
socketIO.wait(seconds=1) 
+3

Heh, zatoczyliśmy pełne koło, widząc, że pakiet socketIO-client został utworzony z powiązanego pytania SO: http://stackoverflow.com/questions/6692908/formatting-messages-to-send-to-socket-io -node-js-server-from-python-client –

+0

Otrzymuję ostrzeżenie OSTRZEŻENIE: root: localhost: 8000/socket.io [oczekiwanie na połączenie] ("Połączenie przerwane.", błąd (111, "Odmowa połączenia"))...możesz pomóc? – 3ppps

+0

Czy działa serwer socket.io? Którą wersję serwera socket.io używasz? –