"Connection refused" Autobahn Android to Java EE Endpoint - java

I have a Java EE Endpoint set up on a Payara server to which I attempt to connect an Android client using Autobahn WebSockets. I have the following setup:
My WebSocket Endpoint on the server:
public class CommunicationSocket extends Endpoint {
#Override
public void onOpen(Session aSession, EndpointConfig aConfig) {
aSession.addMessageHandler(new MessageHandler.Whole<byte[]>() {
#Override
public void onMessage(byte[] aMessage) {
// Do something fun
}
});
}
}
I register the WebSocket as such:
public class RegisterSocket implements ServerApplicationConfig {
#Override
public Set<ServerEndpointConfig> getEndpointConfigs(
Set<Class<? extends Endpoint>> aEndpointClasses) {
Set<ServerEndpointConfig> result = new HashSet<>();
for (Class endpointClass : aEndpointClasses) {
if (endpointClass.equals(CommunicationSocket.class)) {
ServerEndpointConfig sec
= ServerEndpointConfig.Builder.create(endpointClass,
"/WebSocket").build();
result.add(sec);
}
}
return result;
}
#Override
public Set<Class<?>> getAnnotatedEndpointClasses(
Set<Class<?>> aScanned) {
return Collections.emptySet();
}
}
The WebSocket can now be reached att ws://localhost:46588/Server/WebSocket. I've confirmed that it works with the following javascript in chrome:
function WebSocketTest() {
if ("WebSocket" in window) {
ws = new WebSocket("ws://localhost:46588/Server/WebSocket");
ws.onopen = function() {
ws.send("Message to send");
alert("Message is sent...");
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
alert("Message is received... \n" + received_msg);
};
} else {
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
}
}
However when I try to connect with my android client using autobahn, the socket closes without being able to establish a connection with the message "Connection refused". I use the following code in onCreate to connect (mSocket is a field of the activity class):
WebSocketHandler messageHandler = new WebSocketHandler() {
#Override
public void onOpen() {
System.out.println("Connected...");
}
#Override
public void onClose(int code, String reason) {
System.out.println("Socket closing: " + reason);
mSocket = null;
}
#Override
public void onTextMessage(String payload) {
System.out.println("Received: " + payload);
}
#Override
public void onBinaryMessage(byte[] payload) {
System.out.println("Message received: " + payload);
}
};
mSocket = new WebSocketConnection();
try {
String address = "ws://localhost:46588/Server/WebSocket";
mSocket.connect(address, messageHandler);
} catch (WebSocketException e) {
System.out.println("Could not connect to WebSocket: "
+ e.getMessage());
mSocket = null;
}
I have internet permissions i my manifest as so:
<uses-permission android:name="android.permission.INTERNET">
</uses-permission>
Is there anything in my code or approach that is wrong? Is it possible to log/catch the event of connecting (handshake or what not) in order to shed light onto why the connection is refused?

And as I got ready to post the question I googled one last time: lo and behold, localhost is not the localhost of the machine running the emulator (I guess it's the localhost of the emulated device). So use:
10.0.2.2:[port]
instead of
localhost:[port]
and it will be fine on the emulator (don't forget to change if running on an actual device)

Related

Socket.io emit and listener functions not working on Android

I'm trying to connect my Android client to Node JS server using Socket.IO. Connection is successful but I can't emit or listen to any data change.
Here is my Android code...
socket = IO.socket("http://192.168.0.101:3000");
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
System.out.println("Connected");
socket.emit("message","test");
}
}).on("message", new Emitter.Listener() {
#Override
public void call(Object... args) {
System.out.println("Message : "+args[0]);
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
System.out.println("Socket disconnected");
}
}).on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
#Override
public void call(Object... args) {
System.out.println("Error In Socket Connection "+args[0]);
}
});
socket.connect();
Socket is connecting to server perfectly. I'm getting the "connected" message in log. But that "message" event isn't working. What am I doing wrong? ;_;
You need to use OkHttp. Add this to your Gradle dependencies:
implementation("com.squareup.okhttp3:okhttp:4.8.1")
Then add this as a field in the activity or fragment class:
private var socket: Socket? = null
Then this is how you get your socket instance for example in onCreate() method of the activity or fragment:
val okHttpClient: OkHttpClient = OkHttpClient.Builder().build()
IO.setDefaultOkHttpWebSocketFactory(okHttpClient)
IO.setDefaultOkHttpCallFactory(okHttpClient)
val opts = IO.Options()
opts.apply {
callFactory = okHttpClient
webSocketFactory = okHttpClient
}
socket = try {
IO.socket("http://10.0.2.2:3000", opts)
} catch (e: URISyntaxException) {
null
}
(This code is written in kotlin language)
Then everything should work fine.

Where I may wrong while connected to StompClient?

I need help with connect on android to my WebSocket server based on Spring boot. Source code of this server I have taken https://spring.io/guides/gs/messaging-stomp-websocket/
Everything works fine on server and browser client on this sample,
but if I use StompClient (https://github.com/NaikSoftware/StompProtocolAndroid) to connect on my socket I am getting mStompClient.isConnected() == false and conand mStompClient.send(...) doesn't send anything (?).
After few minutes socketweb server closes the connection and I get in my log: '~~ Stomp connection closed'.
Web server locates on Heroku cloud system.
There is my connecting code from android activity:
private StompClient mStompClient;
private void connectStomp(){
mStompClient = Stomp.over(WebSocket.class, "wss://myserver/gs-guide-websocket");
mStompClient.topic("/topic/greetings").subscribe(new Action1<StompMessage>() {
#Override
public void call(StompMessage stompMessage) {
Log.w(TAG, "== "+stompMessage.getPayload());
}
});
mStompClient.connect();
mStompClient.lifecycle().subscribe(new Action1<LifecycleEvent>() {
#Override
public void call(LifecycleEvent lifecycleEvent) {
switch (lifecycleEvent.getType()) {
case OPENED:
Log.w(TAG, "~~ Stomp connection opened");
break;
case ERROR:
Log.e(TAG, "~~ Error", lifecycleEvent.getException());
break;
case CLOSED:
Log.w(TAG, "~~ Stomp connection closed "+lifecycleEvent.getMessage());
break;
}
}
});
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
connectStomp();
}
// Send test request to server
public void onSend(View view){
Log.w(TAG,"onSend: click");
mStompClient.send("/app/hello","Test").subscribe(new Observer<Void>() {
#Override
public void onCompleted() {
Log.w(TAG, "~~~~ onCompleted");
}
#Override
public void onError(Throwable e) {
Log.w(TAG, "~~~~ onCompleted "+e.getMessage());
}
#Override
public void onNext(Void aVoid) {
Log.w(TAG, "~~~~ onNext ");
}
});
if (mStompClient.isConnected()){
mStompClient.send("/app/hello","test msg").subscribe();
Log.w("aaaa : ","onCreate: connected");
}
}
It would be my mistake but if I connect to my server socket with spring boot WebSocketStompClient everithing works fine:
private SockJsClient sockJsClient;
private WebSocketStompClient stompClient;
private final WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
#Before
public void setup() {
List<Transport> transports = new ArrayList<>();
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
this.sockJsClient = new SockJsClient(transports);
this.stompClient = new WebSocketStompClient(sockJsClient);
this.stompClient.setMessageConverter(new MappingJackson2MessageConverter());
}
#Test
public void getGreeting() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<Throwable> failure = new AtomicReference<>();
StompSessionHandler handler = new TestSessionHandler(failure) {
#Override
public void afterConnected(final StompSession session, StompHeaders connectedHeaders) {
session.subscribe("/topic/greetings", new StompFrameHandler() {
#Override
public Type getPayloadType(StompHeaders headers) {
return Greeting.class;
}
#Override
public void handleFrame(StompHeaders headers, Object payload) {
Greeting greeting = (Greeting) payload;
try {
System.out.println(greeting.getContent());
assertEquals("Hello, Spring!", greeting.getContent());
} catch (Throwable t) {
System.out.println(t.getMessage());
failure.set(t);
} finally {
session.disconnect();
latch.countDown();
}
}
});
try {
session.send("/app/hello", "Test");
} catch (Throwable t) {
failure.set(t);
latch.countDown();
}
}
};
this.stompClient.connect("wss://myserver/gs-guide-websocket", this.headers, handler, 443);
if (latch.await(10, TimeUnit.SECONDS)) {
if (failure.get() != null) {
throw new AssertionError("", failure.get());
}
}
else {
fail("Greeting not received");
}
}
private class TestSessionHandler extends StompSessionHandlerAdapter {
private final AtomicReference<Throwable> failure;
public TestSessionHandler(AtomicReference<Throwable> failure) {
this.failure = failure;
}
#Override
public void handleFrame(StompHeaders headers, Object payload) {
this.failure.set(new Exception(headers.toString()));
}
#Override
public void handleException(StompSession s, StompCommand c, StompHeaders h, byte[] p, Throwable ex) {
this.failure.set(ex);
}
Any ideas? Thanks a lot!
I used the same Library in order to connect with Stomp based web socket. There were some configurations on the server side. On the android side, I was using URL as starting with "ws://" and ending with "websocket" like "ws://" + SERVER_URL + "/websocket".
See this answer for server side https://stackoverflow.com/a/41751897/5392825

connection to NodeJs and Express.io get error

i'm newbie in nodejs and express.io , in android application i'm wrote this simple code to connect from android or java but iget connection error
app = require('express.io')()
app.http().io()
// Broadcast the new visitor event on ready route.
app.io.route('ready', function(req) {
req.io.broadcast('new visitor')
console.log('ready');
})
// Send client html.
app.get('/', function(req, res) {
//res.sendfile(__dirname + '/client.html')
req.io.broadcast('new visitor')
console.log('hello');
})
app.listen(7076)
this code maybe is correct, after opening http://192.168.1.5:7076 link in browser i get hello message, now with below code i'm try to connect but i get connection error:
private static final String SERVER_ADDRESS = "http://192.168.1.5:7076";
private Socket mSocket;
{
try {
mSocket = IO.socket(SERVER_ADDRESS);
} catch (URISyntaxException e) {
Log.e("Error URI", String.valueOf(e));
throw new RuntimeException(e);
}
}
public class ActivityHome extends FragmentActivity {
...
mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
mSocket.on("new message", onNewMessage);
mSocket.on("user joined", onUserJoined);
mSocket.on("user left", onUserLeft);
mSocket.on("typing", onTyping);
mSocket.on("stop typing", onStopTyping);
mSocket.connect();
...
}
private Emitter.Listener onConnectError = new Emitter.Listener() {
#Override
public void call(Object... args) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"CONNECT ERROR", Toast.LENGTH_LONG).show();
}
});
}
};

how to add http server inside android applicaton and access from mobile browser

I want to add a http server inside the android application. I have tried NanoHTTPD server taken from https://github.com/NanoHttpd/nanohttpd. So I am able to run this http server as simple java class in my desktop . and able to access it from desktop browser.
Now I want to add this code with android application and start this server inside android device and access it from my mobile device browser.Is is possible and is there any other server i can bind with my android app .
Here is my working sample code. It has limitation as activity will removed from memory my server will stop. To remove that I will write a service for this task.
public class MainActivity extends Activity {
private static final int PORT = 8080;
private MyHTTPD server;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
server = new MyHTTPD();
try {
server.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (server != null)
server.stop();
}
private class MyHTTPD extends NanoHTTPD {
public MyHTTPD() {
super(8080);
}
#Override public Response serve(IHTTPSession session) {
Method method = session.getMethod();
String uri = session.getUri();
System.out.println(method + " '" + uri + "' ");
String msg = "<html><body><h1>Hello server</h1>\n";
Map<String, String> parms = session.getParms();
if (parms.get("username") == null)
msg +=
"<form action='?' method='get'>\n" +
" <p>Your name: <input type='text' name='username'></p>\n" +
"</form>\n";
else
msg += "<p>Hello, " + parms.get("username") + "!</p>";
msg += "</body></html>\n";
return new NanoHTTPD.Response(msg);
}
}
}
//now access web page using http://127.0.0.1:8080
This code works:
private class MyHTTPD extends NanoHTTPD {
public MyHTTPD() throws IOException {
super(8080);
}
#Override
public Response serve(String uri, String method, Properties header, Properties parms, Properties files) {
InputStream is = new FileInputStream("/sdcard/1.mp3");
return new NanoHTTPD.Response(HTTP_OK, "audio/mp3", is);
}
}
server = new MyHTTPD();
server.start();
// and now you can use http://localhost:8080 to do something (ex : streaming audio ...)

Jetty9 WebSocket Client - SessionFactory.createSession causes java.lang.NullPointerException

I'm new to Jerry, and trying to implement WebSocket Client on Jetty9.
I saw an example on Jetty8.
org.eclipse.jetty.websocket Class WebSocketClient
http://archive.eclipse.org/jetty/8.0.0.v20110901/apidocs/org/eclipse/jetty/websocket/WebSocketClient.html
to create a new instance of WebSocketClient is :
WebSocketClientFactory factory = new WebSocketClientFactory();
factory.start();
WebSocketClient client = factory.newWebSocketClient();
// Configure the client
WebSocket.Connection connection = client.open(new
URI("ws://127.0.0.1:8080/"), new WebSocket.OnTextMessage()
{
public void onOpen(Connection connection)
{
// open notification
}
public void onClose(int closeCode, String message)
{
// close notification
}
public void onMessage(String data)
{
// handle incoming message
}
}).get(5, TimeUnit.SECONDS);
connection.sendMessage("Hello World");
However, I've never seen a document for Jetty9 for this.
So far, referring to
org.eclipse.jetty.websocket.common
Interface SessionFactory
//----------------------------------------------
WebSocketSession createSession(URI requestURI,
EventDriver websocket,
LogicalConnection connection)
//----------------------------------------------
I've tried
private WebSocketSessionFactory factory = new WebSocketSessionFactory();
try
{
WebSocketSession session = factory.createSession(uri,
eventDriver, connection);
RemoteEndpoint ep = session.getRemote();
}
catch (Exception ex)
{
System.out.println("=ERROR= " + ex);
//=ERROR= java.lang.NullPointerException
}
private EventDriver eventDriver = new EventDriver()
{
#Override
public WebSocketPolicy getPolicy()
{
return null;
}
//......................................
#Override
public void incomingFrame(Frame frame)
{
}
};
private LogicalConnection connection = new LogicalConnection()
{
#Override
public void close()
{
}
//...............................
#Override
public void resume()
{
}
};
but I've encounter java.lang.NullPointerException
How do we implement Jetty9 WebSocket Client ??
Thanks for your advise.
Hope this helpful: EventClient.java

Categories

Resources