Initial Java Client(#2521)
This commit is contained in:
parent
8a69fb7f51
commit
6b3437deb7
|
|
@ -13,4 +13,6 @@ repositories {
|
|||
|
||||
dependencies {
|
||||
testImplementation group: 'junit', name: 'junit', version: '4.12'
|
||||
compile "org.java-websocket:Java-WebSocket:1.3.8"
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
public interface Action<T> {
|
||||
void invoke(T param);
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Chat {
|
||||
public static void main(String[] args) throws URISyntaxException, InterruptedException {
|
||||
System.out.println("Enter the URL of the SignalR Chat you want to join");
|
||||
Scanner reader = new Scanner(System.in); // Reading from System.in
|
||||
String input;
|
||||
input = reader.nextLine();
|
||||
HubConnection hubConnection = new HubConnection(input);
|
||||
|
||||
hubConnection.On("Send", (message) -> {
|
||||
String newMessage = ((JsonArray) message).get(0).getAsString();
|
||||
System.out.println("REGISTERED HANDLER: " + newMessage);
|
||||
});
|
||||
|
||||
//This is a blocking call
|
||||
hubConnection.start();
|
||||
|
||||
while (!input.equals("leave")){
|
||||
// Scans the next token of the input as an int.
|
||||
input = reader.nextLine();
|
||||
hubConnection.send("Send", input);
|
||||
}
|
||||
|
||||
hubConnection.stop();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
public class DefaultJsonProtocolHandShakeMessage {
|
||||
String protocol = "json";
|
||||
int version = 1;
|
||||
}
|
||||
|
|
@ -1,8 +1,99 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class HubConnection {
|
||||
public boolean methodToTest(){
|
||||
return true;
|
||||
private String _url;
|
||||
private ITransport _transport;
|
||||
private OnReceiveCallBack callback;
|
||||
private HashMap<String, Action> handlers = new HashMap<>();
|
||||
private JsonParser jsonParser = new JsonParser();
|
||||
private static final String RECORD_SEPARATOR = "\u001e";
|
||||
|
||||
public Boolean connected = false;
|
||||
|
||||
public HubConnection(String url) {
|
||||
_url = url;
|
||||
callback = (payload) -> {
|
||||
String[] messages = payload.split(RECORD_SEPARATOR);
|
||||
|
||||
for (String splitMessage : messages) {
|
||||
|
||||
// Empty handshake response "{}". We can ignore it
|
||||
if (splitMessage.length() == 2) {
|
||||
continue;
|
||||
}
|
||||
processMessage(splitMessage);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
_transport = new WebSocketTransport(_url);
|
||||
} catch (URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void processMessage(String message) {
|
||||
JsonObject jsonMessage = jsonParser.parse(message).getAsJsonObject();
|
||||
String messageType = jsonMessage.get("type").toString();
|
||||
switch(messageType) {
|
||||
case "1":
|
||||
//Invocation Message
|
||||
String target = jsonMessage.get("target").getAsString();
|
||||
if (handlers.containsKey(target)) {
|
||||
handlers.get(target).invoke(jsonMessage.get("arguments"));
|
||||
}
|
||||
break;
|
||||
case "2":
|
||||
//Stream item
|
||||
//Don't care yet
|
||||
break;
|
||||
case "3":
|
||||
//Completion
|
||||
//Don't care yet
|
||||
break;
|
||||
case "4":
|
||||
//Stream invocation
|
||||
//Don't care yet;
|
||||
break;
|
||||
case "5":
|
||||
//Cancel invocation
|
||||
//Don't care yet
|
||||
break;
|
||||
case "6":
|
||||
//Ping
|
||||
//Don't care yet
|
||||
break;
|
||||
case "7":
|
||||
// Close message
|
||||
//Don't care yet;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void start() throws InterruptedException {
|
||||
_transport.setOnReceive(this.callback);
|
||||
_transport.start();
|
||||
connected = true;
|
||||
}
|
||||
|
||||
public void stop(){
|
||||
_transport.stop();
|
||||
connected = false;
|
||||
}
|
||||
|
||||
public void send(String method, Object arg1) {
|
||||
InvocationMessage message = new InvocationMessage(method, new Object[]{ arg1 });
|
||||
_transport.send(message);
|
||||
}
|
||||
|
||||
public void On(String target, Action callback) {
|
||||
handlers.put(target, callback);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
public interface ITransport {
|
||||
void start() throws InterruptedException;
|
||||
void send(InvocationMessage invocationMessage);
|
||||
void setOnReceive(OnReceiveCallBack callback);
|
||||
void onReceive(String message);
|
||||
void stop();
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
public class InvocationMessage {
|
||||
private int type = 1;
|
||||
String invocationId;
|
||||
String target;
|
||||
Object[] arguments;
|
||||
|
||||
public InvocationMessage(String target, Object[] args) {
|
||||
this.target = target;
|
||||
arguments = args;
|
||||
}
|
||||
|
||||
public String getInvocationId() {
|
||||
return invocationId;
|
||||
}
|
||||
|
||||
public void setInvocationId(String invocationId) {
|
||||
this.invocationId = invocationId;
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(String target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public Object getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public void setArguments(Object[] arguments) {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public interface OnReceiveCallBack {
|
||||
void invoke(String message);
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.java_websocket.client.WebSocketClient;
|
||||
import org.java_websocket.handshake.ServerHandshake;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
public class WebSocketTransport implements ITransport {
|
||||
private static final String RECORD_SEPARATOR = "\u001e";
|
||||
private WebSocketClient _webSocket;
|
||||
private OnReceiveCallBack onReceiveCallBack;
|
||||
private URI _url;
|
||||
|
||||
public WebSocketTransport(String url) throws URISyntaxException {
|
||||
// To Do: Format the incoming URL for a websocket connection.
|
||||
_url = new URI(url);
|
||||
_webSocket = createWebSocket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws InterruptedException {
|
||||
_webSocket.connectBlocking();
|
||||
_webSocket.send(createHandshakeMessage() + RECORD_SEPARATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(InvocationMessage invocationMessage) {
|
||||
Gson gson = new Gson();
|
||||
String message = gson.toJson(invocationMessage) + RECORD_SEPARATOR;
|
||||
_webSocket.send(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnReceive(OnReceiveCallBack callback) {
|
||||
this.onReceiveCallBack = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(String message) {
|
||||
this.onReceiveCallBack.invoke(message);
|
||||
}
|
||||
|
||||
private String createHandshakeMessage() {
|
||||
Gson gson = new Gson();
|
||||
return gson.toJson(new DefaultJsonProtocolHandShakeMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
_webSocket.closeConnection(0, "HubConnection Stopped");
|
||||
}
|
||||
|
||||
private WebSocketClient createWebSocket() {
|
||||
return new WebSocketClient(_url) {
|
||||
@Override
|
||||
public void onOpen(ServerHandshake handshakedata) {
|
||||
System.out.println("Connected to " + _url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
onReceive(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(int code, String reason, boolean remote) {
|
||||
System.out.println("Connection Closed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception ex) {
|
||||
System.out.println("Error: " + ex.getMessage());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -6,9 +6,8 @@ import org.junit.Test;
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
public class HubConnectionTest {
|
||||
// Coming soon!
|
||||
@Test
|
||||
public void testEmptyCollection() {
|
||||
HubConnection hubConnection = new HubConnection();
|
||||
assertTrue(hubConnection.methodToTest());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue