I am trying to get started with WebSockets, and trying to write a simple application to send messages back and forth via a websoket.
However, it looks like the socket that I am trying to create never gets connected. Why can that be?
Below is the code of my WebSockets class. When .onConnect() is called, it logs:
I am socket, I was connected. Am i connected? - false
Update: in JavaScript, where I create the socket in question, the readyState is 1, which means "socket open, communication is possble".
import a.b.Misc; //writes logs.
import com.sun.grizzly.websockets.BaseServerWebSocket;
import com.sun.grizzly.websockets.DataFrame;
import com.sun.grizzly.websockets.WebSocketListener;
public class ChatWebSocket_v2 extends BaseServerWebSocket {
private String user;
public ChatWebSocket_v2(WebSocketListener... listeners) {
super(listeners);
}
public String getUser() {
if (user == null) {
Misc.print("User is null in ChatWebSocket");
throw new NullPointerException("+=The user is null in chat web socket");
}
return user;
}
public void setUser(String user) {
Misc.print("Just set user: " + user);
this.user = user;
}
#Override
public void onMessage(String message) {
Misc.print(message +"\n");
}
#Override
public void onMessage(byte[] message) {
Misc.print(new String(message) +" << Bytes\n");
}
#Override
public void onConnect() {
Misc.print("I am socket, i was connected. Am i connected? - " + this.isConnected());
}
#Override
public void onClose(DataFrame df) {
Misc.print("I am socket, i was closed");
}
}
If you're just trying to make a connection somewhere, you might want to try this instead. There is a live working demo and you can download the javascript code and play with it yourself. Note that the javascript code only works if you have it installed on a server (due to browser security because it's 'fancy'.) There is also a step by step browser-based client tutorial in the works that I will post as soon as it's ready. Most proxy servers haven't been upgraded to handle websockets so they will screw up connection request and most people won't be able to connect to websocket servers from work. Firefox 7 (release) or Google Chrome 14 or later support the latest version of the websocket protocol that the demo server runs.
If you want to try to get the grizzly demo working, you might have some debugging to do and maybe I'll help with that. Note that in comments below the article, other people said they couldn't get it working either and I haven't found any follow up. At this point it seems no better than the echo app above even if we do get it running and is possibly overly complicated and underly documented if you're just trying to get started. But if you want to try to get it running, you should 'git' the latest version of the code here, which was at least committed recently and may be fixed.
Then make sure that app.url in the application javascript file is set to your installation directory. His is hard-coded as:
url: 'ws://localhost:8080/grizzly-websockets-chat/chat',
If you're using Firefox 7, the javascript needs to be modified to use the Moz prefix, for example:
if (typeof MozWebSocket != "undefined") { // window.MozWebSocket or "MozWebSocket" in window
ok
} else if (window.WebSocket) { // he uses if ("WebSocket" in window)
ok
} else {
do your print "browser doesn't support websockets"
}
.... then if the browser supports websockets
websocket = new WebSocket(app.url); or
websocket = new MozWebSocket(app.url);
// depending on which it is.
The HLL websocket server demo code has this all sorted out.
(another) UPDATE: As I work through grizzly myself, I found on the Quick Start in the glassfish admin console, there's a hello sample that's pretty easy to set up and run. You'll find instructions there. The sample directory also contains a war file named: websocket-mozilla; so I guess its supposed to use websockets. Someone who's familiar with jsp should review the source code. All I can see is that it's using an http session. No mention of a websocket at all. It's a lot like the hello sample.
Related
It's been days that I struggle to make a basic Client / server communication using websockets
My client is a java client with libGDX and my server is a basic java server
My main goal is to compile my client into HTML5 to communicate with my server using websockets.
I tryed the following solution when searching on google :
https://github.com/czyzby/gdx-lml/tree/master/websocket
https://github.com/pepedeab/libGDX-Net
https://github.com/TooTallNate/Java-WebSocket
The 1 seemed to be the best solution but, it doesn't seems to have the TCP_NODELAY socket setting (which is essential in my case)
The 2 seemed an other good solution too, But it relies on http://code.google.com/p/gwt-ws/(which at this time don't understand the point of this)
The 3 is what I choosed, a simple WebSocket Java API to let me write client and server really easily.
It worked very well for desktop and android, but when I tryed to html:dist, gradle give me error about websocket which was not inherit etc...
My main build.gradle file contains this line for each project (core, desktop, android, html) : compile "org.java-websocket:Java-WebSocket:1.3.7"
So to resume my primary question : How to correctly establish a websocket connection with a client compiled with GWT in ligdx, with in addition TCP_NODELAY?
My client is a very simple class :
package com.mygdx.game;
import java.net.URI;
import java.nio.ByteBuffer;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.handshake.ServerHandshake;
public class WebSocketsNet extends WebSocketClient {
public WebSocketsNet(URI serverUri, Draft draft) {
super(serverUri, draft);
}
public WebSocketsNet(URI serverURI) {
super(serverURI);
}
#Override
public void onOpen(ServerHandshake handshakedata) {
send("Hello, it is me. Mario :)");
System.out.println("new connection opened");
}
#Override
public void onClose(int code, String reason, boolean remote) {
System.out.println("closed with exit code " + code + " additional info: " + reason);
}
#Override
public void onMessage(String message) {
System.out.println("received message: " + message);
}
#Override
public void onMessage(ByteBuffer message) {
System.out.println("received ByteBuffer");
}
#Override
public void onError(Exception ex) {
System.err.println("an error occurred:" + ex);
}}
According to https://bugs.webkit.org/show_bug.cgi?id=102079 and https://groups.google.com/forum/#!topic/native-client-discuss/T8zdrMjiTAE, found via https://github.com/websockets/ws/issues/791 and https://github.com/varspool/Wrench/pull/104, most browsers already use TCP_NODELAY. At least from the websocket standard, there is nothing you can do to influence this on the client - on the server there may be more options.
If TCP_NODELAY is already set on the client, you can set it on the server as well to ensure both sides are sending small messages as soon as possible.
Another thought that is suggested in questions like https://stackoverflow.com/a/13406438/860630 is to respond to every message sent right away, so that the network stack flushes all remaining messages as soon as possible.
Finaly I found a way to make it work, so I post a answer here for those interested.
I used https://github.com/czyzby/gdx-lml/tree/master/websocket
Particulary the example package, and rigorously follow everything that need to be added on build.gradle and on differents xml files, so now it work !
So to conclude :
Server Listening websockets with java-web-socket
LIBGDX client use gdx-websockets to connect to the server (Watch-out for different build gradle file and xml !!)
Hope to help some people who were in the same problem like me !
I am currently writing a small Java applet to access HBase data using the REST API. Accessing the data using Java is not particularly difficult, I have done this successfully. When running on a machine in my HDP cluster, the results are perfect. However when running as an applet I get no results at all. (I have chosen an applet since distributing an executable JAR is something my boss wants to avoid)
Having finally found what I believe to be the underlying issue, I have found the following runtime exception: hbase-default.xml file seems to be for an older version of HBase (null), this version is 1.1.2.2.4.0.0-169. My assumption is that this is caused by the fact that my local machine does not have HBase at all. The intention is that users will be able to view their own data from a local machine, and so I cannot expect all users to have HBase (or anything other than a browser)
My question really has two parts:
Is there anyway to get an applet like this to work?
Is there a better alternative to an applet for this kind of work?
Posting my code in case I have made some significant mistake:
public class HBaseConnector extends JApplet
{
private Cluster cluster;
public void init()
{
System.out.println("Applet initialising");
cluster = new Cluster();
cluster.add("hbase_server", 9080);
}
public void start()
{
System.out.println("Applet starting");
Client client = new Client(cluster);
RemoteHTable table = new RemoteHTable(client, "table_name");
Get get = new Get(Bytes.toBytes("key"));
get.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("Record"));
try
{
Result result1 = table.get(get);
JOptionPane.showMessageDialog(null, Bytes.toString(result1.getValue(Bytes.toBytes("f1"), Bytes.toBytes("Record"))), "Result", JOptionPane.INFORMATION_MESSAGE);
}
catch (Exception ex)
{
System.err.println("Exception occurred");
}
}
public void stop()
{
System.out.println("Applet stopping");
}
public void destroy()
{
System.out.println("Applet destroyed");
}
}
While I haven't been able to solve this problem for an applet itself, I managed to get the app working by moving over the a JNLP app (JNLP). Given this, I suspect the underlying problem was a permissions issue due to the fact that applets run in a sandbox. This is fine, since I am aware that most browsers are moving away from Java plugins.
Another possible cause I discovered: hbase-default.xml must be in the root folder of the jar.
I'm testing PHP/Java Bridge connection. And I have a simple example yet.
The php file is:
require_once("http://localhost:8087/JavaBridge/java/Java.inc");
$world = new java("HelloWorld");
echo $world->hello(array("from PHP"));
And the java file:
import javax.swing.JOptionPane;
public class HelloWorld {
public static final String JAVABRIDGE_PORT="8087";
static final php.java.bridge.JavaBridgeRunner runner =
php.java.bridge.JavaBridgeRunner.getInstance(JAVABRIDGE_PORT);
public static void main(String args[]) throws Exception {
runner.waitFor();
System.exit(0);
}
public void hello(String args[]) throws Exception {
JOptionPane.showMessageDialog(null, "hello " + args[0]);
}
}
Everything works fine on one pc. But I have to implement connection from PHP server to java desktop application which is on the another server not on localhost, so "localhost:8087/JavaBridge/java/Java.inc" won't work. In future this java app will print on printer some data from php website.
So I need to call java function remotely. It should be a desktop App because I will write usb connection in future. Please help me, thanks.
You can't use require_once to include files from another host.
If this option is available, a lot of websites will be at risk.
Why don't you use it from another way, Here are some points that may help:
make java calls PHP.
write your result to some file in the destination server.
Make server reads that file.
If you don't like that, please read about web service, it may have what you need.
when a user executes a command, I would like to send the output back to only that user, not the channel.
I'm using the PircBotX framework.
My Code:
public void onMessage(MessageEvent<PircBotX> event) {
if (event.getMessage().equalsIgnoreCase("!test")){
event.respond("Test Successful.");
}else if (event.getMessage().split(" ")[1].equalsIgnoreCase("!test2")){
event.getChannel().send().message("this response works");
event.respond("This response works");
event.getUser().send().message("but this does not work");
}
}
According to the documentation, event.getUser().send().message("XYZ"); should be a private message.
The documentation also states bot.sendMessage should be a private message, but that this doesn't work either.
For both of these, the console output looks completely normal.
One thought I have as to the origin of the issue: I'm building this as a Twitch.tv chat bot. It is possible (although their API page does not mention this) that private messages are disabled.
are you trying to send a whisper ?? if so take a look at this https://discuss.dev.twitch.tv/t/sending-whispers-with-my-irc-bot/4346/6 you need to connect to an extra irc server to send whisper/private messages
try event.respondPrivateMessage("response");
See pirocbotx-docs->MessageEvent.respondPrivateMessage(String response)
I am building a GWT app. Previously, whenever I requested an image from the web-page, that request went to a client-class, and that class used to serve the image. This worked for both GWT generated URL as well as the standalone file URL after compilation.
But now I have replaced that part with a Ajax (RPC) call to the server, where the serverside class is receiving the necessary parameters from the client-class, and serving the image, which is being sent by the client-class to the UI. This works fine with GWT generates URL, but after compilation, when I am trying to run it as a standalone HTML (by giving the path to the file in the URL bar), no Ajax request is fired.
Is is because the RPC call needs a server to respond to (in contrast to jQuery Ajax calls, which work jolly well in desktop alone)? How can I mimic the Ajax behavior in Desktop mode also? The call looks something like this:
private final GreetingServiceAsync response = GWT.create(GreetingService.class); //(I haven't changed the defualt names..:))
response.greetServer(i, j,new AsyncCallback<String,String>() { // i,j is already calculated, server needs to know these to pass an image url
public void onSuccess(String url1, String url2) {...}
public void onFailure(Throwable caught) {...}
});
You completely came out of the GWT structure .
Once you compile your project the all GWT code coverts into JavaScript.
Even though there is no server running and if you accessed your html file from file system like C://myapp/myapp.html . the browser will serves that as a static web
page ..ofcourse inside that html page there will be your app.nochahe.js which is pure javascript .
So with out any hesitations the browser displays the all content ..but it wil never become an so called web application and it never make any ajax or any other server
call.
In your case you are not running any server and accessing them as a static pages and expecting them to connect server and bring your data which is quite impossible .
So first of all please run||debug your code in development mode.
After started running or Debugging the project ..the generated url in the development mode tab will look like below .
h t t p : / / localhost : 8888 / MyModule.html ? gwt.codesvr = localhost : 9997
You may have a doubt regarding the parameter gwt.codesvr.
It runs your client-side Java code, which is compiled to class files, but not yet to JavaScript files.
Once done with your implementations compile the project and export you war folder on any server to test or access and access them as
ex:localhost:8080/myapp/someservice.
Coming to the so called AJAX calls ,They are RPC's in the GWT .RPC is the GWT internal structure to communicate with the server ,normally they are all impl classes in general ,those extends RemoteServiceServlet which serves the data to client on HTTP protocol and impossible to evoke them without running server.
If you still have a confusion about different GWT application modes refer this Differences link
You mean if you just open HTML host page directly from the file system? This can not work, since you don't have a server then. That way there is no server-side which could answer your RPC call. You have to run your GWT app in a servlet container (like Tomcat or Jetty), so that the server-side RPC servlet is running and ready to answer the RPC calls from the client.
Even if you are running a server somewhere. The RPC call can not not where to find the server, if you just open the file from the file system. The RPC call uses the URL (host page base URL) to locate its server. In your case this is file://C/something instead of http://www.hererunsaserver.com/.
You could probably embed your data within the app, to achieve some kind of desktop mode. But I don't know whether this is what you are up to?
This should be feasable. You have to implement the onFailure, because it will be called if no server is available.
Make a new Class for AsyncCallback something like this, (by default AsyncCallback has only one parameter, have you implemented it with two?):
public class UrlCallback implements AsyncCallback<String, String> {
private String url1;
private String url2;
public UrlCallback(String url1, String url2) {
this.url1 = url1;
this.url2 = url2;
}
#Override
public void onSuccess(String result1, String result2) {
//"Do what you want to do here"
}
#Override
public void onFailure(Throwable caught) {
//Respond the static file here
}
}
I handle it in my case, to server image-urls from localstorage when i have no internet connection:
public class PictureCallback implements AsyncCallback<Picture> {
private Image picture;
private IAppRequestTransportSupport storage;
private String storeId;
public PictureCallback(String storeId, Image picture) {
this.picture = picture;
this.storage = new AppLocalStorageSupport();
this.storeId = storeId;
}
#Override
public void onSuccess(Picture result) {
picture.setUrl(result.getImageUrl());
storage.doOnSuccess(result.getImageUrl(), "picture"+storeId);
}
#Override
public void onFailure(Throwable caught) {
try {
String pic = storage.readFromLocaleStorage("picture"+storeId);
if(pic != null && !pic.equals("")) {
picture.setUrl(pic);
}
} catch (KeyNotFoundException e) {
e.printStackTrace();
} catch (NoLocaleStorageSupportException e) {
e.printStackTrace();
}
}
}