2014-01-17 58 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

相关问题