2017-10-19 14 views
0

Hey Je suis nouveau python et voici le code du serveur Websocket dans une tornadeComment envoyer un message du serveur au client spécifique dans une tornade websocket

import tornado.ioloop 
import tornado.web 
import tornado.websocket 
import tornado.template 

class MainHandler(tornado.web.RequestHandler): 
    def get(self): 
    loader = tornado.template.Loader(".") 
    self.write(loader.load("index.html").generate()) 

class WSHandler(tornado.websocket.WebSocketHandler): 
    def open(self): 
    print 'connection opened...' 
    self.write_message("The server says: 'Hello'. Connection was accepted.") 

    def on_message(self, message): 
    self.write_message("The server says: " + message + " back at you") 
    print 'received:', message 

    def on_close(self): 
    print 'connection closed...' 

application = tornado.web.Application([ 
    (r'/ws', WSHandler), 
    (r'/', MainHandler), 
    (r"/(.*)", tornado.web.StaticFileHandler, {"path": "./resources"}), 
]) 

if __name__ == "__main__": 
    application.listen(9090) 
    tornado.ioloop.IOLoop.instance().start() 

Il fonctionne correctement et recevoir mes messages (messages client) sur le serveur mais malheureusement, il ne m'envoie pas d'autres messages de clients. Comme je html ce

<!DOCTYPE html> 
<html> 
<head> 
    <title>WebSockets Client</title> 
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
</head> 
<body> 
Enter text to send to the websocket server: 
<div id="send"> 
    <input type="text" id="data" size="100"/><br> 
    <input type="button" id="sendtext" value="send text"/> 
</div> 
<div id="output"></div> 
</body> 
</html> 
<script> 

jQuery(function($){ 

    if (!("WebSocket" in window)) { 
    alert("Your browser does not support web sockets"); 
    }else{ 
    setup(); 
    } 


    function setup(){ 

    // Note: You have to change the host var 
    // if your client runs on a different machine than the websocket server 

    var host = "ws://localhost:9090/ws"; 
    var socket = new WebSocket(host); 
    console.log("socket status: " + socket.readyState); 

    var $txt = $("#data"); 
    var $btnSend = $("#sendtext"); 

    $txt.focus(); 

    // event handlers for UI 
    $btnSend.on('click',function(){ 
     var text = $txt.val(); 
     if(text == ""){ 
     return; 
     } 
     socket.send(text); 
     $txt.val("");  
    }); 

    $txt.keypress(function(evt){ 
     if(evt.which == 13){ 
     $btnSend.click(); 
     } 
    }); 

    // event handlers for websocket 
    if(socket){ 

     socket.onopen = function(){ 
     //alert("connection opened...."); 
     } 

     socket.onmessage = function(msg){ 
     showServerResponse(msg.data); 
     } 

     socket.onclose = function(){ 
     //alert("connection closed...."); 
     showServerResponse("The connection has been closed."); 
     } 

    }else{ 
     console.log("invalid socket"); 
    } 

    function showServerResponse(txt){ 
     var p = document.createElement('p'); 
     p.innerHTML = txt; 
     document.getElementById('output').appendChild(p); 
    } 


    } 





}); 

</script> 

Quand je suis frappé bouton envoyer du client (en utilisant ci-dessus html) il envoyer mon message au serveur, mais je veux envoyer mon message à un autre client. Comment puis-je envoyer mon message du serveur à un autre client comme client souhaité. Le lien donné dans le commentaire m'a fourni un moyen (faire une variable de liste globale, ajouter chaque client dedans, puis boucle et envoyer un message dans l'événement de message) pour envoyer mon message à tous les clients mais je veux aussi mon message à client spécifique .

+0

Copie possible de [Websockets avec Tornado: Obtenir l'accès depuis "l'extérieur" pour envoyer des messages aux clients] (https://stackoverflow.com/questions/23562465/websockets-with-tornado-get-access-from-the -outside-to-send-messages-to-clien) –

+0

@BenDarnell Le lien que vous avez fourni ne couvre pas la façon d'envoyer un message à un client spécifique. –

+0

La solution de base est la même - enregistrez une référence à 'self' de votre méthode' open', puis appelez 'write_message' plus tard. Comment vous identifiez ce client est à vous. –

Répondre

0

Vous avez besoin d'un système externe pour cela. Comme Ben Darnell l'a dit, d'autres questions expliquent certaines façons primitives de rassembler les clients.

Ce dont vous avez besoin est de rassembler une sorte d'ID de chaque client lors de l'initialisation. Cela peut être un compte de votre système, ou vous pouvez générer un nouveau pour chaque nouvelle connexion:

import uuid 

clients = {} 

class WSHandler(tornado.websocket.WebSocketHandler): 
    def __init__(self, application, request, **kwargs): 
     super(WSHandler, self).__init__(application, request, **kwargs) 
     self.client_id = str(uuid.uuid4()) 

    def open(self): 
     print 'connection for client {0} opened...'.format(self.client_id) 
     clients[self.client_id] = self 
     self.write_message("The server says: 'Hello'. Connection was accepted.") 

    def on_message(self, message): 
     self.write_message("The server says: " + message + " back at you") 
     print 'received:', message 

    def on_close(self): 
     clients.pop(self.client_id, None) 
     print 'connection closed...' 

Plus tard, vous pouvez utiliser ce composé complètement client_id de dire aux autres clients qu'un client avec cet identifiant existe. Plus tard vous pouvez lui envoyer un message avec

clients[<id>].write_message("Hello!") 

En note, cependant, cette approche ne sera pas bien à l'échelle. En fait, vous ne pourrez adresser que des clients connectés à l'instance de tornade en cours. Si vous avez besoin de plusieurs instances et d'un moyen d'atteindre un client, consultez les courtiers de messagerie tels que rabbitmq.