Websocket 客户端简单示例

有没有人能给我提供一个非常简单的例子,使用 javax.websocket的网络套接字客户端?

我想连接到 websocket (ws:// socket.example.com : 1234) ,发送消息(添加频道)和收听消息。所有消息(发送和收听)都是 JSON 格式的。

顺便问一下,这个库是最适合简单的 websocket 通信的吗?

286240 次浏览

我在这里发现了一个使用 javax.websocket的很好的例子:

Http://www.programmingforliving.com/2013/08/jsr-356-java-api-for-websocket-client-api.html

这里的代码基于上面链接的示例:

TestApp.java:

package testapp;


import java.net.URI;
import java.net.URISyntaxException;


public class TestApp {


public static void main(String[] args) {
try {
// open websocket
final WebsocketClientEndpoint clientEndPoint = new WebsocketClientEndpoint(new URI("wss://real.okcoin.cn:10440/websocket/okcoinapi"));


// add listener
clientEndPoint.addMessageHandler(new WebsocketClientEndpoint.MessageHandler() {
public void handleMessage(String message) {
System.out.println(message);
}
});


// send message to websocket
clientEndPoint.sendMessage("{'event':'addChannel','channel':'ok_btccny_ticker'}");


// wait 5 seconds for messages from websocket
Thread.sleep(5000);


} catch (InterruptedException ex) {
System.err.println("InterruptedException exception: " + ex.getMessage());
} catch (URISyntaxException ex) {
System.err.println("URISyntaxException exception: " + ex.getMessage());
}
}
}

WebsocketClientEndpoint.java :

package testapp;


import java.net.URI;
import javax.websocket.ClientEndpoint;
import javax.websocket.CloseReason;
import javax.websocket.ContainerProvider;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;


/**
* ChatServer Client
*
* @author Jiji_Sasidharan
*/
@ClientEndpoint
public class WebsocketClientEndpoint {


Session userSession = null;
private MessageHandler messageHandler;


public WebsocketClientEndpoint(URI endpointURI) {
try {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(this, endpointURI);
} catch (Exception e) {
throw new RuntimeException(e);
}
}


/**
* Callback hook for Connection open events.
*
* @param userSession the userSession which is opened.
*/
@OnOpen
public void onOpen(Session userSession) {
System.out.println("opening websocket");
this.userSession = userSession;
}


/**
* Callback hook for Connection close events.
*
* @param userSession the userSession which is getting closed.
* @param reason the reason for connection close
*/
@OnClose
public void onClose(Session userSession, CloseReason reason) {
System.out.println("closing websocket");
this.userSession = null;
}


/**
* Callback hook for Message Events. This method will be invoked when a client send a message.
*
* @param message The text message
*/
@OnMessage
public void onMessage(String message) {
if (this.messageHandler != null) {
this.messageHandler.handleMessage(message);
}
}


@OnMessage
public void onMessage(ByteBuffer bytes) {
System.out.println("Handle byte buffer");
}


/**
* register message handler
*
* @param msgHandler
*/
public void addMessageHandler(MessageHandler msgHandler) {
this.messageHandler = msgHandler;
}


/**
* Send a message.
*
* @param message
*/
public void sendMessage(String message) {
this.userSession.getAsyncRemote().sendText(message);
}


/**
* Message handler.
*
* @author Jiji_Sasidharan
*/
public static interface MessageHandler {


public void handleMessage(String message);
}
}

TooTallNate 有一个简单的客户端 https://github.com/TooTallNate/Java-WebSocket

只需将 dist 文件夹中的 java _ websocket.jar 添加到项目中。

 import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_10;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONException;
import org.json.JSONObject;


WebSocketClient mWs = new WebSocketClient( new URI( "ws://socket.example.com:1234" ), new Draft_10() )
{
@Override
public void onMessage( String message ) {
JSONObject obj = new JSONObject(message);
String channel = obj.getString("channel");
}


@Override
public void onOpen( ServerHandshake handshake ) {
System.out.println( "opened connection" );
}


@Override
public void onClose( int code, String reason, boolean remote ) {
System.out.println( "closed connection" );
}


@Override
public void onError( Exception ex ) {
ex.printStackTrace();
}


};
//open websocket
mWs.connect();
JSONObject obj = new JSONObject();
obj.put("event", "addChannel");
obj.put("channel", "ok_btccny_ticker");
String message = obj.toString();
//send message
mWs.send(message);

//和关闭 websocket

 mWs.close();

看一下来自 Arun Gupta 的 JavaEE7示例。

我叉了它 在 Github 上

Main

/**
* @author Arun Gupta
*/
public class Client {


final static CountDownLatch messageLatch = new CountDownLatch(1);


public static void main(String[] args) {
try {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
String uri = "ws://echo.websocket.org:80/";
System.out.println("Connecting to " + uri);
container.connectToServer(MyClientEndpoint.class, URI.create(uri));
messageLatch.await(100, TimeUnit.SECONDS);
} catch (DeploymentException | InterruptedException | IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

客户端点

/**
* @author Arun Gupta
*/
@ClientEndpoint
public class MyClientEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("Connected to endpoint: " + session.getBasicRemote());
try {
String name = "Duke";
System.out.println("Sending message to endpoint: " + name);
session.getBasicRemote().sendText(name);
} catch (IOException ex) {
Logger.getLogger(MyClientEndpoint.class.getName()).log(Level.SEVERE, null, ex);
}
}


@OnMessage
public void processMessage(String message) {
System.out.println("Received message in client: " + message);
Client.messageLatch.countDown();
}


@OnError
public void processError(Throwable t) {
t.printStackTrace();
}
}

使用这个库 org.java _ websocket

首先,您应该将该库导入 build.gradle

repositories {
mavenCentral()
}

然后在依赖项{}中添加实现

implementation "org.java-websocket:Java-WebSocket:1.3.0"

然后你就可以用这个代码

在 Websocketclient 的活动声明对象中,类似于

private WebSocketClient mWebSocketClient;

然后为回调添加此方法

 private void ConnectToWebSocket() {
URI uri;
try {
uri = new URI("ws://your web socket url");
} catch (URISyntaxException e) {
e.printStackTrace();
return;
}


mWebSocketClient = new WebSocketClient(uri) {
@Override
public void onOpen(ServerHandshake serverHandshake) {
Log.i("Websocket", "Opened");
mWebSocketClient.send("Hello from " + Build.MANUFACTURER + " " + Build.MODEL);
}


@Override
public void onMessage(String s) {
final String message = s;
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView textView = (TextView)findViewById(R.id.edittext_chatbox);
textView.setText(textView.getText() + "\n" + message);
}
});
}


@Override
public void onClose(int i, String s, boolean b) {
Log.i("Websocket", "Closed " + s);
}


@Override
public void onError(Exception e) {
Log.i("Websocket", "Error " + e.getMessage());
}
};
mWebSocketClient.connect();

}

I have Spring 4.2 in my project and many SockJS Stomp implementations usually work well with Spring Boot implementations. 来自 Baeldung 的实施 worked(for me without changing from Spring 4.2 to 5). After Using the dependencies mentioned in his blog, it still gave me ClassNotFoundError. I added the below dependency to fix it.

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>

下面是来自 -com.nevisionary.ws.client. Web socket-https://github.com/TakahikoKawasaki/nv-websocket-client的这样一个解决方案

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketAdapter;
import com.neovisionaries.ws.client.WebSocketException;
import com.neovisionaries.ws.client.WebSocketFactory;
import com.neovisionaries.ws.client.WebSocketFrame;


public class WssM {


public static List<String> ListMessage = new ArrayList<>();
public static boolean WebSocketLog = true;
public static final String WssURL = "wss://site.com/api/sport_tree_ws/v1";
public static final String WebsocketMessage = "{\"type\": \"subscribe_state\", \"subscribe_state\": {\"uid\": \"-1\"}}";


    



public static void main(String[] args) throws IOException, WebSocketException {
WebSocket socket = connect(WssURL);
BufferedReader in = getInput();
socket.sendText(WebsocketMessage);
String text;
try {
while ((text = in.readLine()) != null) {
if (text.equals("exit")) break;
if (!socket.isOpen()) {
System.out.println("Socket is closed. Trying to reconnect...");
socket.recreate().connect();
System.out.println("Reconnected!");
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (socket.isOpen()) {
System.out.println("Disconnecting connection to server!");
socket.disconnect(); //Close the WebSocket.
}
}
}
private static WebSocket connect(String Host) throws IOException, WebSocketException {
WebSocketFactory wsFactory = new WebSocketFactory().setConnectionTimeout(55000);
WebSocket socket = wsFactory.createSocket(URI.create(Host)).addProtocol("json");//.addHeader("Sec-WebSocket-Protocol", "json")
//WebSocket socket = wsFactory.createSocket(URI.create(HOST + "?Authorization=" + DUMMY_JWT_TOKEN));
socket.addListener(new WebSocketAdapter() {
@Override
public void onSendingHandshake(WebSocket websocket, String requestLine, List<String[]> headers) {
if (WebSocketLog) System.out.println(requestLine);
for (String[] header : headers) { //Print the header, "{name}: {value}"
if (WebSocketLog) System.out.format("%s: %s\n", header[0], header[1]);
}
}
@Override
public void onConnected(WebSocket websocket, Map<String, List<String>> headers) {
if (WebSocketLog) System.out.println("Success! WebSocket - Connected!");
}
@Override
public void onTextMessage(WebSocket websocket, String text) {
if (WebSocketLog) System.out.printf("MessageToClient: %s%n", text); ListMessage.add(text);
}
@Override
public void onDisconnected(WebSocket websocket, WebSocketFrame serverCloseFrame, WebSocketFrame clientCloseFrame, boolean closedByServer) {
if (WebSocketLog) System.out.println("Disconnecting...");
if (WebSocketLog) System.out.printf(" Opcode: %d%n", serverCloseFrame.getOpcode());
}
@Override
public void onPongFrame(WebSocket websocket, WebSocketFrame frame) {
if (WebSocketLog) System.out.printf("Received some pong..!! Payload text: %s%n", frame.getPayloadText());
System.out.printf(" Opcode: %d%n", frame.getOpcode());
}
@Override
public void onPingFrame(WebSocket websocket, WebSocketFrame frame) {
if (WebSocketLog) System.out.printf("I have been pinged by server at %s%n", LocalDateTime.now());
websocket.sendPong("Ponging from client");
}
@Override
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) {
if (WebSocketLog) System.out.printf("onTextFrame - %s%n", LocalDateTime.now());
websocket.sendPong("onTextFrame from client");
}
@Override
public void onError(WebSocket websocket, WebSocketException cause) {
System.out.printf("I have received exception %s%n", cause.getMessage());
}
}).connect();
return socket;
}


private static BufferedReader getInput() {
return new BufferedReader(new InputStreamReader(System.in));
}
}