2013-03-26 12 views
12

Jest to prawdopodobnie oczywiste, ale jestem nowy w tym paradygmacie. Tworzę serwer Jetty i rejestruję swoją klasę websocket w następujący sposób:Jak uzyskać dostęp do instancji WebSockets w Jetty 9?

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

Websocket odbiera wiadomości w porządku. Chciałbym również móc wysyłać wiadomości z serwera bez uprzedniego otrzymania wiadomości od klienta. Jak uzyskać dostęp do instancji MyEchoSocket utworzonej po otwarciu połączenia? Lub, bardziej ogólnie, w jaki sposób wysyłać wiadomości w gnieździe poza metodą onText w MyEchoSocket?

+0

To nie jest dokładnie serwer. Nie byłoby sensu, aby rozpocząć wysyłanie od tego momentu, ponieważ nie wiesz, z kim jesteś połączony, chyba że odpowiadasz (obsługujesz) kogoś. –

+0

Powodem dla którego pracuję z WebSockets jest to, że uważam, że były dobrym wyborem w sytuacjach, w których chcesz naciskać od strony serwera. MyEchoSocket może śledzić własne WebSocketConnections za pomocą metody onConnect(). Po prostu nie wiem, jak uzyskać dostęp do wystąpienia MyEchoSocket po uruchomieniu programu. –

+0

Do kogo jednak chcesz się popchnąć? Jeśli jest po tym, jak ktoś się do ciebie połączył, to może odradzisz asynchroniczną procedurę obsługi, aby przeprowadzić pchanie. –

Odpowiedz

27

Dwie powszechne techniki, przedstawione tutaj w super uproszczonej koncepcji czatu.

Wariant nr 1: Czy websocket zgłosić swój stan z powrotem do centrum miasta

@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 
    } 
} 

Następnie wystarczy skorzystać z centralnej lokalizacji, aby rozmawiać z WebSocket chcesz.

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

// or 

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

Wariant nr 2: Czy websocket być tworzone ręcznie z 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)); 
    } 
} 

W tym momencie można użyć tych samych technik jak wyżej rozmawiać z WebSocket chcesz.

+2

Po raz kolejny przychodzę na ratunek na polu bitwy na Jetty. Bardzo doceniane! –

+0

Nie należy używać 'private List members = Collections.synchronizedList (new ArrayList <>());' tutaj? –

+0

Optymalizacje/ulepszenia są zawsze potrzebne. Przykłady są tylko podstawami, aby zrozumieć techniki, nie podane jako kompletny/funkcjonalny/zoptymalizowany kod. –

Powiązane problemy