Background:
Using WebSockets with JavaScript + Play! framework (2.2).
Can send and receive data fine in Chrome.
Can only receive data (from server) in Firefox as send() doesn't trigger any callbacks.
In addition to the send issue, and in Firefox only again, the tab for the page is always stuck on "connecting" while the spinner keeps spinning (see figure 1).
Misbehaving Browser:
Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0)(Firefox 24.0)
(Figure 1. Firefox tab after page has loaded and data is shown)
Any time I refresh the web page, I receive the error below, attributed to the constant page loading behaviour I'm sure.
The connection to ws://localhost:9000/ was interrupted while the page was loading.
The entire JavaScript code:
$(function() {
var chatSocket = new WebSocket("#routes.Application.getMetaData().webSocketURL(request)");
var sendMessage = function() {
chatSocket.send(JSON.stringify({
id: "unique",
name: "a name",
age: 22
}));
}
var receiveEvent = function(event) {
var data = JSON.parse(event.data)
document.write(data.age);
document.write(data.name);
document.write(data.message);
document.write("\n");
sendMessage();
chatSocket.close();
}
chatSocket.onmessage = receiveEvent
})
Now In the past, I've been trying with MozWebSocket instead of the standard WebSocket, but I get nothing rendered on screen using that module therefore unless there is an angle I've missed, WebSocket is the better one to use.
The relevant Play! block:
public static WebSocket<JsonNode> getMetaData() {
return new WebSocket<JsonNode>() {
// Called when the Websocket Handshake is done.
public void onReady(WebSocket.In<JsonNode> in, WebSocket.Out<JsonNode> out) {
// For each event received on the socket,
in.onMessage(new Callback<JsonNode>() {
#Override
public void invoke(JsonNode jsonNode) {
System.out.println("Message Incoming!");
System.out.println(jsonNode.get("id"));
System.out.println(jsonNode.get("name"));
System.out.println(jsonNode.get("age"));
}
});
// When the socket is closed.
in.onClose(new Callback0() {
public void invoke() {
System.out.println("Disconnected");
}
});
ObjectNode node = Json.newObject();
node.put("message", "hello");
node.put("name", "client");
node.put("age", 1);
out.write(node);
//same result commented/uncommented
out.close();
}
};
}
So in Chrome, the flow would be:
document.write(...)
"Message Incoming!"
... JSON attributes
"Disconnected"
But in Firefox, the flow is:
document.write(...)
"Disconnected"
Any help in diagnosing these problems would be greatly appreciated. I have no intention of supporting IE, but having both Mozilla and Chrome working would be great.
Other JavaScript Warnings:
Below is a warning I occasionally get in Firefox's console while pointing at the "ws" protocol as the culprit. What its relevance is to my problem, I do not know.
Use of getPreventDefault() is deprecated. Use defaultPrevented instead.
You call document.write() after the document is loaded, which then implies document.open() which in turn replaces the document and by that unloads the old one and aborts stuff like timeouts or websockets.
Use something other than document.write() and you should be fine.
Related
I'm totally desperate trying to do this. I Started a new job where I was given an app made in Processing and now I need it to call a simple index.html(https://west-4f2bc.firebaseapp.com) but not opening it on the browser.
Is there anyway to do it?
later I'm going to pass data adding parameters in URL but now I just need to call it as it is without a window opening.
Please Help me.....
I tried a lot of variants of this code
import processing.net.*;
Client myClient;
void setup() {
// Connect to the local machine at port 10002.
// This example will not run if you haven't
// previously started a server on this port.
myClient = new Client(this, "west-4f2bc.firebaseapp.com", 80);
// Say hello
myClient.write("GET /\r\n");
}
void draw() {
}
Thanks.
With this I only get true, so it connects but I only get 0.
import processing.net.*;
Client myClient;
int dataIn;
void setup() {
size(200, 200);
// Connect to the local machine at port 5204.
// This example will not run if you haven't
// previously started a server on this port.
myClient = new Client(this, "west-4f2bc.firebaseapp.com", 80);
println(myClient.active());
println(dataIn);
}
void draw() {
}
with this I get connected but after Client SocketException: Socket closed
import processing.net.*;
Client myClient;
int dataIn;
void setup() {
Client client;
client = new Client(this, "west-4f2bc.firebaseapp.com", 80);
if (client.active()==true) {
println("connected");
// Make a HTTP request:
client.write("GET /call.html?id=ola&nome=artur\r\n");
client.write("\r\n");
client.stop();
} else {
// if you didn't get a connection to the server:
println("connection failed");
}
}
I've never really used Processing's Networking library, but from what I can tell it's not usually used to read data from a website- it's used for lower-level communication between a client and server. It might be possible to use it to read a website, but what you have already looks more complicated than it has to be.
Remember that Processing is built on top of Java, so anything you can do in Java, you can do in Processing. If I were you, I would do a google search for "java read website" for a ton of results, including:
Reading Directly from a URL
How to read a text file directly from Internet using Java?
Reading website's contents into string
How to read a text from a web page with Java?
Using Java to pull data from a webpage?
I used another library.
import http.requests.*;
void setup()
{
size (100, 100);
}
void draw()
{
PostRequest post = new PostRequest("https://"+"www.example.com");
post.send();
System.out.println("Reponse Content: " + post.getContent());
System.out.println("Reponse Content-Length Header: " + post.getHeader("Content-Length"));
noLoop();
}
Still doesnt does my final objective but at least it can communicate with the page.
I'm very new to Javascript and I have a button that need to be constantly checked against whether a server is active or not.
I'm using the Play framework based in Java. I already have a class ServerStatus that returns whether a service is healthy or not but I am not sure how to link this into my page which contains the button.
Basically, what I want is that if the server goes down then I want the button disabled so that the user cannot use it while the server is unavailable.
I looked a bit at Websockets and that looks really complex. I wasn't sure if there is a simpler way.
EDIT
Using Websockets: I had a read around and it seems I need to use the onmessage event. I found some sample code but I am not sure how to put this into my (document).ready function.
Below I have some code:
$(document).ready(function(){
var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket;
var chatSocket = new WS("routes");//This does not seem to accept any #routes
var lastState = 'unknown';
chatSocket.onmessage = function(e){
var server_message = e.data;
//do something here about enabling and disabling
console.log(server_message);
}
});
function disable()
{
//disable all buttons
}
function enable()
{
//enable all buttons
}
I am lost as to how to add the websocket here.
I am borrowing heavy from this similar question and answer
The basic code is here:
var isNotWorking = false;
var myFunc = function(){
$.ajax({url: "YOUR_URL_HERE",
type: "HEAD",
timeout:1000,
statusCode: {
200: function (response) {
//alert('Working!');
isNotWorking =false;
},
400: function (response) {
//alert('Not working!');
isNotWorking = true;
},
0: function (response) {
//alert('Not working!');
isNotWorking = true;
}
}
});
$('#mybutton').prop('disabled', isNotWorking);
doSetTimeOut();
}
var doSetTimeOut = function(){
setTimeout(function(){
myFunc();
}, 1000);
}
doSetTimeOut();
See a working JS fiddle here
I am trying to migrate a Blackberry application from OS 6 to OS 7 (my app currently works on OS 6). Theoretically it should not cause any problems, but I found an issue that I still cannot resolve. When executing calls to web services (SOAP), I'm setting the HttpMessages to use the POST method, but when the call is executed, it arrives at the server as a GET. This is a big problem for me because the Sever with which am working doesn't support GET's (always results in an "Http 500 error"). This issue doesn't occur on the simulator, just on the device.
Do you know any workaround for this? Is it a problem with OS version? (See below for the code that I'm using).
Device
Model: Bold 9930
Carrier: Sprint
OS: 7.0 Bundle 1296 (v7.0.0.241, Platform 5.0.0.442)
Simulator (On the simulator side I don't have any problems)
Model: Bold 9930
OS: 7.0 Bundle 1962(v7.0.0.440, Sept_24_2011_signed, Platform 4.0.0.141)
public void run() {
context.setEnableBtnsend(false);
BlockingSenderDestination blockSendDest = null;
try {
URI uri = URI.create(URL_BASE);
blockSendDest
= (BlockingSenderDestination) DestinationFactory.getSenderDestination(
senderContext.getName(), uri);
if (blockSendDest == null) {
blockSendDest = DestinationFactory.createBlockingSenderDestination(
senderContext, uri);
}
ByteMessage requestMessage = blockSendDest.createByteMessage();
requestMessage.setTransportHeader("Content-Type", "text/xml;charset=UTF-8");
requestMessage.setTransportHeader("SOAPAction", "\"\"");
// getBodyRequest() -> Insert SOAP request, works fine, was tested on SOAP UI
requestMessage.setStringPayload(getBodyRequest());
((HttpMessage) requestMessage).setMethod(HttpMessage.POST);
blockSendDest.resume();
Message response = blockSendDest.sendReceive(requestMessage);
if (response != null) {
procesMessageResponse(response);
}
// ...
}
catch (Exception ex) {
handleException(ex);
}
I have a GWT based page that I would like to create an HTML snapshot for it using HtmlUnit.
The page loads using Ajax/JavaScript information on a product, so for about 1 second there is a Loading... message and then the content appears.
The problem is that HtmlUnit doesn't seem to capture the information and all I'm getting is the "Loading..." span.
Below is an experimental code with HtmlUnit where I try to give it enough time to wait for the loading of the data but it doesn't seem to change anything and I am still unable to capture the data loaded by the GWT javascript.
WebClient webClient = new WebClient();
webClient.setJavaScriptEnabled(true);
webClient.setThrowExceptionOnScriptError(false);
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
WebRequest request = new WebRequest(new URL("<my_url>"));
HtmlPage page = webClient.getPage(request);
int i = webClient.waitForBackgroundJavaScript(1000);
while (i > 0)
{
i = webClient.waitForBackgroundJavaScript(1000);
if (i == 0)
{
break;
}
synchronized (page)
{
System.out.println("wait");
page.wait(500);
}
}
webClient.getAjaxController().processSynchron(page, request, false);
System.out.println(page.asXml());
Any ideas...?
Thank you for responding.
I actually should have reported this sooner that I have found the solution myself.
Apparently when initialising WebClient with FF:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
It seem to be working.
When initialising WebClient with the default constructor it uses IE7 by default and I guess FF has better support for Ajax and is the recommended emulator to use.
I believe by default NicelyResynchronizingAjaxController will only resynchronize AJAX calls that were caused by a user action, by tracking which thread it originated from. Perhaps the GWT generated JavaScript is being called by some other thread which NicelyResynchronizingAjaxController does not want to wait for.
Try declaring your own AjaxController to synchronize with everything regardless of originating thread:
webClient.setAjaxController(new AjaxController(){
#Override
public boolean processSynchron(HtmlPage page, WebRequest request, boolean async)
{
return true;
}
});
As documentation states, waitForBackgroundJavaScript is experimental:
Experimental API: May be changed in next release and may not yet work perfectly!
The next approach has always worked for me, regardless of the BrowserVersion used:
int tries = 5; // Amount of tries to avoid infinite loop
while (tries > 0 && aCondition) {
tries--;
synchronized(page) {
page.wait(2000); // How often to check
}
}
Note aCondition is whatever you're checking for. EG:
page.getElementById("loading-text-element").asText().equals("Loading...")
None of the so far provided solutions worked for me. I ended up with Dan Alvizu's solution + my own hack:
private WebClient webClient = new WebClient();
public void scrapPage() {
makeWebClientWaitThroughJavaScriptLoadings();
HtmlPage page = login();
//do something that causes JavaScript loading
waitOutLoading(page);
}
private void makeWebClientWaitThroughJavaScriptLoadings() {
webClient.setAjaxController(new AjaxController(){
#Override
public boolean processSynchron(HtmlPage page, WebRequest request, boolean async)
{
return true;
}
});
}
private void waitOutLoading(HtmlPage page) {
while(page.asText().contains("Please wait while loading!")){
webClient.waitForBackgroundJavaScript(100);
}
}
Needless to say, "Please wait while loading!" should be replaced with whatever text is shown while your page is loading. If there is no text, maybe there is a way to check for existence of some gif (if that is used). Of course, you could simply provide a big enough milliseconds value if you're feeling adventurous.
Hi I have the followig code:
page1.jsp
The ajax function called on click of button
function ajaxFunction()
{
var xmlHttp;
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{
alert("Data loaded");
}
}
xmlHttp.open("GET","page2.jsp",true);
xmlHttp.send(null);
}
page2.jsp
<%# page import="javax.jms.*" %>
<%!
private QPublisher qPublisher = null;
public class QPublisher {
private TopicPublisher publisher = null;
private TopicSession session = null;
public void configPublisher(){
TopicConnectionFactory factory = null;
TopicConnection connection = null;
try {
factory = new com.tibco.tibjms.TibjmsTopicConnectionFactory("tcp");
connection = factory.createTopicConnection("user","pwd");
session = connection.createTopicSession(false,javax.jms.Session.AUTO_ACKNOWLEDGE);
javax.jms.Topic topic = session.createTopic("topic1");
publisher = session.createPublisher(topic);
}
}
public void publish(String msg)
{
javax.jms.TextMessage message = session.createTextMessage();
message.setText(msg);
publisher.publish(message);
}
}
public void jspInit(){
qPublisher = new QPublisher();
qPublisher.configPublisher();
}
%>
<%
qPublisher.publish("This is a test for TT");
%>
If I call page2.jsp without using ajax, i.e from page1.jsp using
<form action="page2.jsp">
the message is picked by the subsciber and displayed.
but not by making an ajax..
I have basic idea of ajax, so please guide what am i missing?
I know this isn't really an answer to your question, but if you're not too coupled to using strict JSP and JMS you may want to investigate frameworks that do the plumbing for you.
For example, this is a video of a presentation on How using Grails to build twitter in 40 minutes. The presentation is by Graeme Rocher [twitter] - CTO of G2One, now owned by Spring Source. In the presentation, Graeme creates a fully functional, AJAX enabled, searchable, secure, JMS based twitter clone.
I'm sure there are similar examples for other web frameworks.
Like someone once said - "Don't reinvent the wheel, unless you're really interested in learning alot of low-level detail about wheels"
Are you sure that the Ajax code successfully invokes the page2.jsp? To verify this, you could simply replace the JMS related code with something more simple, just a JSP command which shows "Hello World" in the client.