2014-01-17 97 views
7

我正在開發一個需要用戶之間進行實時交互的項目。我想有一個HTML5 Web客戶端(足夠簡單),並且還有一個本地客戶端(最好是Java),它們都能夠連接到服務器。我已經做了一些研究,並沒有找到一個確定的答案,以確定本地客戶端是否可以在沒有瀏覽器的情況下連接到服務器。沒有瀏覽器的Java Websocket客戶端

問:有沒有辦法從本地Java客戶端連接到websocket服務器而無需瀏覽?我已經看到了其他語言中的一些瀏覽器包裝可能會使這成爲可能。如果沒有,我願意接受建議。

謝謝。

+0

可能重複:http://stackoverflow.com/questions/7257068/java-websocket-client-needed?lq=1 – blackcompe

回答

5

您也可以考慮使用JSR 356 - Java API for WebSocket。它是Java EE 7的一部分,但客戶端可以從普通的Java SE運行而不會出現任何問題。可以使用多種實現方式,現在和下面將在所有這些工作:

編程API:

final WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer(); 

    Session session = webSocketContainer.connectToServer(new Endpoint() { 
     @Override 
     public void onOpen(Session session, EndpointConfig config) { 
      // session.addMessageHandler(...); 
     } 
    }, URI.create("ws://some.uri")); 

註解API:

public static void main(String[] args) throws IOException, DeploymentException { 
    final WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer(); 
    webSocketContainer.connectToServer(MyEndpoint.class, URI.create("ws://some.uri")); 
} 

@ClientEndpoint 
public static class MyEndpoint { 

    // text 
    @OnMessage 
    void onMessage(Session session, String message) { 
     // ... 
    } 

    // binary 
    @OnMessage 
    void onMessage(Session session, ByteBuffer message) { 
     // ... 
    } 

    // @OnClose, @OnOpen, @OnError 
} 

請詳情見鏈接的頁面(全規格)。

這裏有各種實現,基本上每個Java容器都有一個。我正在開發Glassfish/WebLogic實現,並且它的Tyrus可以隨時試用(我們提供易於使用的所有功能,請參閱http://search.maven.org/...)。

8

您肯定可以在瀏覽器沙箱以外的Java中使用桌面應用程序中的WebSockets。這背後的想法是,您可以創建創建TCP連接的胖客戶端,所以當然他們應該能夠在這些TCP連接之上創建WebSocket連接。

這樣做的最新和最好的API之一是由Kaazing編寫的,他認爲WebSocket就像一個套接字,可以使用簡單的「ws://」URI來創建。

該API詳細討論on the Kaazing Gateway 5.0 Java WebSocket Documentation site。您可以從的Kaazing here

創建的WebSocket下載普通網關:

import com.kaazing.net.ws.WebSocket; 
    import com.kaazing.net.ws.WebSocketFactory; 

    wsFactory = WebSocketFactory.createWebSocketFactory(); 
    ws = wsFactory.createWebSocket(URI.create("ws://example.com:8001/path")); 
    ws.connect(); // This will block or throw an exception if failed. 

要發送信息,添加一個WebSocketMessageWriter對象:

WebSocketMessageWriter writer = ws.getMessageWriter(); 
    String text = "Hello WebSocket!"; 
    writer.writeText(text); // Send text message 

要接收或接收消息,添加的WebSocket和WebSocketMessageReader物件:

wsFactory = WebSocketFactory.createWebSocketFactory(); 
    ws = wsFactory.createWebSocket(URI.create("ws://example.com:8001/path")); 
    ws.connect(); // This will block or throw an exception if failed. 

    WebSocketMessageReader reader = ws.getMessageReader(); 
    WebSocketMessageType type = null; // Block till a message arrives 
     // Loop till the connection goes away 
     while ((type = reader.next()) != WebSocketMessageType.EOS) { 
     switch (type) { // Handle both text and binary messages 
      case TEXT: 
      CharSequence text = reader.getText(); 
      log("RECEIVED TEXT MESSAGE: " + text.toString()); 
      break; 
      case BINARY: 
      ByteBuffer buffer = reader.getBinary(); 
      log("RECEIVED BINARY MESSAGE: " + getHexDump(buffer)); 
      break; 
     } 
    } 

(完全披露:我曾在Kaazing公司擔任服務器工程師。)

3

Vert.x有一個Java的WebSocket客戶端:

VertxFactory.newVertx() 
    .createHttpClient() 
    .setHost("localhost") 
    .setPort(8080) 
    .connectWebsocket("/ws", new Handler<WebSocket>() { 

      @Override 
      public void handle(final WebSocket webSocket) { 

       // Listen 
       webSocket.dataHandler(new Handler<Buffer>() { 
        @Override 
        public void handle(Buffer buff) { 
         log.info("Received {}", buff.toString()); 
        } 
       }); 

       // Publish 
       webSocket.writeTextFrame("Heya"); 
      } 
     }); 
1

Netty是這樣的任務一個很好的選擇,它是一個高性能的網絡應用程序框架,它支持SSL優雅,這裏是netty websocket client example從網狀github上:

public final class WebSocketClient { 

static final String URL = System.getProperty("url", "ws://127.0.0.1:8080/websocket"); 

public static void main(String[] args) throws Exception { 
    URI uri = new URI(URL); 
    String scheme = uri.getScheme() == null? "ws" : uri.getScheme(); 
    final String host = uri.getHost() == null? "127.0.0.1" : uri.getHost(); 
    final int port; 
    if (uri.getPort() == -1) { 
     if ("ws".equalsIgnoreCase(scheme)) { 
      port = 80; 
     } else if ("wss".equalsIgnoreCase(scheme)) { 
      port = 443; 
     } else { 
      port = -1; 
     } 
    } else { 
     port = uri.getPort(); 
    } 

    if (!"ws".equalsIgnoreCase(scheme) && !"wss".equalsIgnoreCase(scheme)) { 
     System.err.println("Only WS(S) is supported."); 
     return; 
    } 

    final boolean ssl = "wss".equalsIgnoreCase(scheme); 
    final SslContext sslCtx; 
    if (ssl) { 
     sslCtx = SslContextBuilder.forClient() 
      .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); 
    } else { 
     sslCtx = null; 
    } 

    EventLoopGroup group = new NioEventLoopGroup(); 
    try { 
     // Connect with V13 (RFC 6455 aka HyBi-17). You can change it to V08 or V00. 
     // If you change it to V00, ping is not supported and remember to change 
     // HttpResponseDecoder to WebSocketHttpResponseDecoder in the pipeline. 
     final WebSocketClientHandler handler = 
       new WebSocketClientHandler(
         WebSocketClientHandshakerFactory.newHandshaker(
           uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders())); 

     Bootstrap b = new Bootstrap(); 
     b.group(group) 
     .channel(NioSocketChannel.class) 
     .handler(new ChannelInitializer<SocketChannel>() { 
      @Override 
      protected void initChannel(SocketChannel ch) { 
       ChannelPipeline p = ch.pipeline(); 
       if (sslCtx != null) { 
        p.addLast(sslCtx.newHandler(ch.alloc(), host, port)); 
       } 
       p.addLast(
         new HttpClientCodec(), 
         new HttpObjectAggregator(8192), 
         WebSocketClientCompressionHandler.INSTANCE, 
         handler); 
      } 
     }); 

     Channel ch = b.connect(uri.getHost(), port).sync().channel(); 
     handler.handshakeFuture().sync(); 

     BufferedReader console = new BufferedReader(new InputStreamReader(System.in)); 
     while (true) { 
      String msg = console.readLine(); 
      if (msg == null) { 
       break; 
      } else if ("bye".equals(msg.toLowerCase())) { 
       ch.writeAndFlush(new CloseWebSocketFrame()); 
       ch.closeFuture().sync(); 
       break; 
      } else if ("ping".equals(msg.toLowerCase())) { 
       WebSocketFrame frame = new PingWebSocketFrame(Unpooled.wrappedBuffer(new byte[] { 8, 1, 8, 1 })); 
       ch.writeAndFlush(frame); 
      } else { 
       WebSocketFrame frame = new TextWebSocketFrame(msg); 
       ch.writeAndFlush(frame); 
      } 
     } 
    } finally { 
     group.shutdownGracefully(); 
    } 
} 
} 

public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object> { 

private final WebSocketClientHandshaker handshaker; 
private ChannelPromise handshakeFuture; 

public WebSocketClientHandler(WebSocketClientHandshaker handshaker) { 
    this.handshaker = handshaker; 
} 

public ChannelFuture handshakeFuture() { 
    return handshakeFuture; 
} 

@Override 
public void handlerAdded(ChannelHandlerContext ctx) { 
    handshakeFuture = ctx.newPromise(); 
} 

@Override 
public void channelActive(ChannelHandlerContext ctx) { 
    handshaker.handshake(ctx.channel()); 
} 

@Override 
public void channelInactive(ChannelHandlerContext ctx) { 
    System.out.println("WebSocket Client disconnected!"); 
} 

@Override 
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { 
    Channel ch = ctx.channel(); 
    if (!handshaker.isHandshakeComplete()) { 
     handshaker.finishHandshake(ch, (FullHttpResponse) msg); 
     System.out.println("WebSocket Client connected!"); 
     handshakeFuture.setSuccess(); 
     return; 
    } 

    if (msg instanceof FullHttpResponse) { 
     FullHttpResponse response = (FullHttpResponse) msg; 
     throw new IllegalStateException(
       "Unexpected FullHttpResponse (getStatus=" + response.status() + 
         ", content=" + response.content().toString(CharsetUtil.UTF_8) + ')'); 
    } 

    WebSocketFrame frame = (WebSocketFrame) msg; 
    if (frame instanceof TextWebSocketFrame) { 
     TextWebSocketFrame textFrame = (TextWebSocketFrame) frame; 
     System.out.println("WebSocket Client received message: " + textFrame.text()); 
    } else if (frame instanceof PongWebSocketFrame) { 
     System.out.println("WebSocket Client received pong"); 
    } else if (frame instanceof CloseWebSocketFrame) { 
     System.out.println("WebSocket Client received closing"); 
     ch.close(); 
    } 
} 

@Override 
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
    cause.printStackTrace(); 
    if (!handshakeFuture.isDone()) { 
     handshakeFuture.setFailure(cause); 
    } 
    ctx.close(); 
} 
} 
+0

答案應該站在它自己的。請稍微擴大這個答案。 – klutt

相關問題