2013-03-20 6 views
19

Sto eseguendo un'applicazione guru Django.Come emettere l'evento SocketIO sul lato server

devo qualcosa di simile a questa classe

@namespace('/connect') 
class ConnectNamespace(BaseNamespace): 

    def on_send(self, data): 
     # ... 

Tuttavia, se ricevo gli eventi dal client javascript, tutto funziona e per esempio send evento viene elaborato correttamente

Sono un po ' perso se voglio emit qualche evento sul lato server. Posso farlo all'interno della classe con socket.send_packet

Ma ora voglio collegare un evento a post_save segnale, quindi mi piacerebbe send_packet dall'esterno questa classe namespace, un modo di fare questo sarebbe

ConnectNamespaceInstance.on_third_event('someeventname') 

non riesco proprio a capire come posso ottenere l'istanza di ConnectNamespaceInstance

Insomma, voglio solo inviare un evento a JavaScript client dopo che ricevo post_save segnale

+0

http://stackoverflow.com/questions/13504320/socket-io-namespaces-channels-co – catherine

+2

ho ottenuto lo stesso problema, e non riesco a risolvere ... Qualche idea? – jetmc

+0

Mi dispiace ma non penso suggerito duplicato risponde alla mia domanda –

risposta

7

Quello che probabilmente vuole fare è aggiungere una variabile modulo per monitorare le connessioni, dire _connections, in questo modo:

_connections = {} 

@namespace('/connect') 
class ConnectNamespace(BaseNamespace): 

e quindi aggiungere initialize e disconnect metodi che utilizzano alcuni identificatore felice si può fare riferimento in seguito:

def initialize(self, *args, **kwargs): 
    _connections[id(self)] = self 
    super(ConnectNamespace, self).initialize(*args, **kwargs) 

def disconnect(self, *args, **kwargs): 
    del _connections[id(self)] 
    super(ConnectNamespace, self).disconnect(*args, **kwargs) 

Quando è necessario generare un evento, è possibile cercare la connessione corretta nella variabile _connections e attivare l'evento con emit.

(Non ho provato nulla di tutto ciò, ma ho usato uno schema simile in molti altri linguaggi: non vedo alcun motivo per cui questo non funzionerebbe anche in Python).

+1

Mi chiedevo se ci sia qualche strumento incorporato per farlo nel framework, ma questa è una soluzione davvero bella che avrei dovuto pensare! +1 :) grazie –

+0

un esempio per la trasmissione al canale con questa soluzione? –

+1

Questo mi ha aiutato a inviare messaggi sul segnale post_save in Django. Soluzione davvero bella. – kpacn

0

Altro quindi la risposta di Femi, che credo funzioni certamente. Utilizzando Redis avrebbe probabilmente vi darà un po 'più di flessibilità e utilizzando greenlet da gevent possono beneficiare di questo approccio come un po' di più "nel quadro", dal momento che si sta già utilizzando gevent-socketio: D

REDIS_HOST = getattr(settings, 'REDIS_HOST', '127.0.0.1') 


class YourNamespace(BaseNamespace): 

    def _listener(self, channel_label_you_later_call_in_post_save): 
     pubsub = redis.StrictRedis(REDIS_HOST).pubsub() 
     pubsub.subscribe(chan) 
     while True: 
      for i in pubsub.listen(): 
       self.send({'message_data': i}, json=True) 

    def recv_message(self, message): 
     if is_message_to_subscribe(message): 
      self.spawn(self.listener, get_your_channel_label(message)) 

E nel tuo post_save , si può fare

red = redis.StrictRedis(REDIS_HOST) 
red.publish(channel_label, message_data)