2013-03-26 9 views
12

Questo è probabilmente ovvio, ma sono nuovo in questo paradigma. Creo un server Jetty e registrare la mia classe websocket come segue:Come accedere a WebSockets istanziati in Jetty 9?

 Server server = new Server(8080); 
     WebSocketHandler wsHandler = new WebSocketHandler() 
     { 
      @Override 
      public void configure(WebSocketServletFactory factory) 
      { 
       factory.register(MyEchoSocket.class); 
      } 
     }; 
     server.setHandler(wsHandler); 

Il websocket riceve messaggi bene. Vorrei anche essere in grado di inviare messaggi dal server senza aver prima ricevuto un messaggio dal client. Come posso accedere all'istanza MyEchoSocket che viene creata quando si apre la connessione? O, più in generale, come posso inviare messaggi sul socket al di fuori del metodo onText in MyEchoSocket?

+0

Quindi non è esattamente un server. Non avrebbe senso iniziare a inviare da quel momento in quanto non si sa a chi si è connessi, a meno che non si risponda a (servire) qualcuno. –

+0

La ragione per cui lavoro con WebSockets è che ho pensato che fossero una buona scelta per le situazioni in cui si desidera spingere dal lato server. MyEchoSocket può tenere traccia delle proprie WebSocketConnections tramite il suo metodo onConnect(). Solo non so come accedere all'istanza di MyEchoSocket una volta che il programma è in esecuzione. –

+0

Chi stai cercando di spingere? Se è dopo che qualcuno si è connesso a te, allora forse genera un gestore asincrono per fare la spinta. –

risposta

27

Due tecniche comuni, presentate qui in un concetto di chat room super semplificato.

Opzione # 1: Avere WebSocket riferire il suo stato in una posizione centrale

@WebSocket 
public class ChatSocket { 
    public Session session; 

    @OnWebSocketConnect 
    public void onConnect(Session session) { 
     this.session = session; 
     ChatRoom.getInstance().join(this); 
    } 

    @OnWebSocketMessage 
    public void onText(String message) { 
     ChatRoom.getInstance().writeAllMembers("Hello all"); 
    } 

    @OnWebSocketClose 
    public void onClose(int statusCode, String reason) { 
     ChatRoom.getInstance().part(this); 
    } 
} 

public class ChatRoom { 
    private static final ChatRoom INSTANCE = new ChatRoom(); 

    public static ChatRoom getInstance() 
    { 
     return INSTANCE; 
    } 

    private List<ChatSocket> members = new ArrayList<>(); 

    public void join(ChatSocket socket) 
    { 
     members.add(socket); 
    } 

    public void part(ChatSocket socket) 
    { 
     members.remove(socket); 
    } 

    public void writeAllMembers(String message) 
    { 
     for(ChatSocket member: members) 
     { 
      member.session.getRemote().sendStringByFuture(message); 
     } 
    } 

    public void writeSpecificMember(String memberName, String message) 
    { 
     ChatSocket member = findMemberByName(memberName); 
     member.session.getRemote().sendStringByFuture(message); 
    } 

    public ChatSocket findMemberByName(String memberName) 
    { 
     // left as exercise to reader 
    } 
} 

Poi è sufficiente utilizzare la posizione centrale per parlare con i WebSockets di vostra scelta.

ChatRoom.getInstance().writeSpecificMember("alex", "Hello"); 

// or 

ChatRoom.getInstance().writeAllMembers("Hello all"); 

Opzione # 2: Avere WebSocket essere creato manualmente con WebSocketCreator

@WebSocket 
public class ChatSocket { 
    public ChatRoom chatroom; 

    public ChatSocket(ChatRoom chatroom) 
    { 
     this.chatroom = chatroom; 
    } 

    @OnWebSocketConnect 
    public void onConnect(Session session) { 
     chatroom.join(this); 
    } 

    @OnWebSocketMessage 
    public void onText(String message) { 
     chatroom.writeAllMembers(message); 
    } 

    @OnWebSocketClose 
    public void onClose(int statusCode, String reason) { 
     chatroom.part(this); 
    } 
} 

public class ChatCreator implements WebSocketCreator 
{ 
    private ChatRoom chatroom; 

    public ChatCreator(ChatRoom chatroom) 
    { 
     this.chatroom = chatroom; 
    } 

    public Object createWebSocket(UpgradeRequest request, 
            UpgradeResponse response) 
    { 
     // We want to create the Chat Socket and associate 
     // it with our chatroom implementation 
     return new ChatSocket(chatroom); 
    } 
} 

public class ChatHandler extends WebSocketHandler 
{ 
    private ChatRoom chatroom = new ChatRoom(); 

    @Override 
    public void configure(WebSocketServletFactory factory) 
    { 
     factory.setCreator(new ChatCreator(chatroom)); 
    } 
} 

A questo punto è possibile utilizzare le stesse tecniche come sopra per parlare con i WebSockets di vostra scelta.

+2

Ancora una volta venendo in mio soccorso sul campo di battaglia del molo. Molto apprezzato! –

+0

Non dovresti usare 'lista privata membri = Collections.synchronizedList (new ArrayList <>());' qui? –

+0

Ottimizzazioni/miglioramenti sono sempre necessari. Gli esempi sono solo le basi, al fine di comprendere le tecniche, non fornite come codice completo/funzionale/ottimizzato. –