Initial Java Client(#2521)
This commit is contained in:
parent
8a69fb7f51
commit
6b3437deb7
|
|
@ -13,4 +13,6 @@ repositories {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation group: 'junit', name: 'junit', version: '4.12'
|
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.
|
// 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.
|
// 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 class HubConnection {
|
||||||
public boolean methodToTest(){
|
private String _url;
|
||||||
return true;
|
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.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class HubConnectionTest {
|
public class HubConnectionTest {
|
||||||
|
// Coming soon!
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyCollection() {
|
public void testEmptyCollection() {
|
||||||
HubConnection hubConnection = new HubConnection();
|
|
||||||
assertTrue(hubConnection.methodToTest());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue