The onmessage event is not triggering in the WebSocket JavaScript client

I've been diving into learning websockets, and initially had success sending simple strings between peers. However, I hit a roadblock when attempting to send Objects to my client as the onmessage function never seems to fire. Here's the code snippets:

Java serverside:

@ServerEndpoint(value = "/event/{id}",
    encoders={PositionJSONEncoder.class},
    decoders={PositionJSONDecoder.class}
)
public class SocketManager {

private static ConcurrentHashMap<String, Session> users = new ConcurrentHashMap<String, Session>();
@OnMessage
    public void onMessage(Position position, @PathParam("id") String id, Session session) {

        log.info("user "+id+", "+position.toString());
        try {
            for(Entry<String, Session> entry : users.entrySet()) {
                if(!entry.getKey().equals(position.getUserID()) && entry.getValue().isOpen()) {
                    entry.getValue().getBasicRemote().sendObject(position);
                }
            }
        } catch (EncodeException ee) {
            log.error(ee);
        } catch (IOException ioe) {
            log.error(ioe);
        }
    }
}

The serverendpoint encoder (I'll omit the decoder, server handle data correctly):

public class PositionJSONEncoder implements Encoder.Text<Position>{
    
    private Gson gson = new Gson();

    public void destroy() {}

    public void init(EndpointConfig arg0) {}

    public String encode(Position arg0) throws EncodeException {
        return gson.toJson(arg0);
    }
}

The relevant client side (AngularJS):

app.factory('socket', function() {
        var service = {};
        service.ws = {};

        service.connect = function(userID) {
            this.ws = new WebSocket("ws://localhost:8080/event/"+userID);
        };
        service.disconnect = function() {
            if(this.ws != undefined && this.ws != null) {
                this.ws.onclose();
            }
        };
        service.ws.onopen = function() {
            // TODO
        };
        service.ws.onmessage = function(msg) {
            try {
                alert('roba: '+JSON.parse(msg.data));
            } catch(err) {
                alert(err.message);
            }
        };
        service.ws.onclose = function() {
        // TODO
        };
service.ws.onerror = function(evt) {
    alert(evt.data);
};
return service;
});

The model the server send:

public class Position {

    private String userID;
    private Float lat;
    private Float lng;

    public Position() {}

    public String getUserID() {
        return userID;
    }
    public void setUserID(String userID) {
        this.userID = userID;
    }
    public Float getLat() {
        return lat;
    }
    public void setLat(Float lat) {
        this.lat = lat;
    }
    public Float getLng() {
        return lng;
    }
    public void setLng(Float lng) {
        this.lng = lng;
    }

    @Override
    public String toString() {
        return userID+"["+"lat: "+lat+", "+"lng: "+lng+"]";
    }
}

My pom's dependencies:

<dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
        <!-- GSON JSON serializer -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>1.7.1</version>
        </dependency>
</dependencies>

Although the server successfully receives the JSON object from the client, the client is not triggering the onmessage function when receiving a Position object back from the server. The encoder appears to be working fine returning strings such as:

{"userID":"bob","lat":2.0,"lng":2.0}

I can see the websocket carrying the messages:

However, my javascript's onmessage function remains silent. I've also implemented an onerror function with no feedback received either. The framework I'm using is wildfly-8.0.0.Final.

Update: I tried implementing a java websocket client that successfully receives frames sent by the server. Could there be an issue with my AngularJS client?

Answer №1

After troubleshooting, I identified the issue. The problem was that in my javascript client, I had assigned a function to an undefined object. Here is where the mistake occurred:

service.ws.onmessage = function(msg) {
    try {
        alert('roba: '+JSON.parse(msg.data));
    } catch(err) {
        alert(err.message);
    }
};

The reason the onmessage function never fired was because service.ws.onmessage was undefined. To fix this, I modified my angular factory as follows:

app.factory('socket', function() {
    var service = {};
    service.ws = {};

    service.connect = function(userID) {
        this.ws = new WebSocket("ws://localhost:8080/event/"+userID);
        this.ws.onmessage = function(msg) {
            try {
                alert('roba: '+JSON.parse(msg.data).lat+' :: '+JSON.parse(msg.data).lng);
            } catch(err) {
                alert(err.message);
            }
        };
        this.ws.onerror = function(evt) {
            alert('error: '+evt.data);
        };
    };
    service.disconnect = function() {
        if(this.ws != undefined && this.ws != null) {
            this.ws.onclose();
        }
    };
    return service;
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for preventing the unmounting of child components while utilizing JSX's map function

This is a condensed version of a question I previously asked. Hopefully, it's clearer and more comprehensible. Here is a simple application with 3 input fields that accept numbers (disregard the ability to enter non-numbers). The app calculates the s ...

Tips for dividing a single row retrieved from a MySQL database that has been converted with json_encode so that it can be shown in

Looking to extract data from a MySQL query result in one PHP page and transfer it to a separate page with JavaScript. Here is my attempt so far: I am aiming to retrieve specific values from the selected row in the MySQL table and populate them into #event ...

Using readFileSync is causing me some issues. I attempted to display the input after converting it to a string, but the result was unexpected

As a newcomer to Node.js, I am trying to learn on my own. My current task involves reading a file (specified by the first command line argument) and then printing the number of lines in that file. I have been utilizing the readFileSync method for this purp ...

Tips on sorting objects by comparing them to array elements

I have an array called myarrays and an object named obj. I need to filter the object by comparing the elements of the array with the keys of the object. If you want to see the code in action, you can check it out on StackBlitz: https://stackblitz.com/edit ...

I am facing an issue with sending OAuth v1 parameters in a GET request using Axios in Node.js

Attempting to make a request to ADP using autho1.0a encountered some issues. While successful in postman, the same request failed when made through my application. View Postman screenshot Utilized npm module Similar query on stackoverflow Below is t ...

Tips for implementing a smooth fade-in effect while rotating URLs within an iFrame

As I cycle through a list of URLs, I am displaying each one in an iFrame for a specific amount of time based on the corresponding value in the durations array. (function step(){ $j('.marquee').attr('src',urls[i].innerHTML); setTime ...

Chart rendering failure: unable to obtain context from the provided item

I am encountering an issue while trying to incorporate a chart from the charts.js library into my Vue.js and Vuetify application. The error message that keeps popping up is: Failed to create chart: can't acquire context from the given item Even af ...

Missing sidebar display

Hi there! I am having an issue with my sidebar not appearing correctly when I click on the toggle button. It seems to be moving to the side, but the sidebar itself is blank or transparent. I suspect that the problem lies within my JavaScript file. As a beg ...

Invoking servlet using Ajax

I have created a JSP file with Javascript functions and AJAX calls to invoke a servlet (ReadprojectInfo). <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE ...

The Vue DevTools are functioning as expected, but there seems to be an issue

Encountering a peculiar issue where the value displayed in Vue DevTools is accurate, matching what is expected in my data. When I first click on the "Edit" button for an item, the correct value appears in the browser window as intended. However, upon clic ...

Encountering a Laravel Nova issue where attempting to override a Vue component leads to a Vue warning: Error

Recently, I decided to incorporate a user guide into my nova using the following Vue Shepherd library. To make this work, I made some adjustments in the files within the nova directory. One of these changes involved renaming the file "webpack.mix.js.dist" ...

What could be the reason for my jQuery files not being loaded?

I have included jQuery and Bootstrap in my header as follows: <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> <link rel="stylesheet" type="text/css" href="css/style.css"> <link rel="stylesheet" href="https://maxcdn.b ...

I'm having trouble getting jQuery to work properly with Bootstrap buttons

In simple terms, my objective is to have two buttons on a page where "1" is displayed when the first button is pressed and "2" is displayed when the second button is pressed. This functionality works fine with radio inputs, but when I incorporate button la ...

Create a new function within the GraphQL Resolvers file

I am trying to define a function within the same ts file as where I specify the resolvers export const resolvers = { Query: { books: () => { return [ { title: 'Harry Potter and the Chambe ...

Tips for addressing lag problems in my Three.js game as time progresses

My game in Three.js doesn't start off with any lag, but after a few minutes, the performance begins to slow down on computers running it. I've tried reviewing my code and checking my arrays, adjusting values to troubleshoot, but so far, nothing s ...

What is the best way to deactivate a div along with all its contained elements?

Currently, I am facing an issue where I need to deactivate a div element but I am struggling to find a solution. <div ng-repeat="item in items"> <div ng-click="somefunction()">{{some value}}</div> </div> JavaScript: $scope.items ...

The $http success function is returning an undefined variable for a custom AngularJS service

In my recent development project, I created an angular service with the purpose of loading customer details through http requests and storing them for future use using a singleton pattern. However, I encountered an issue where the variable intended to hol ...

Tips for concealing navigation buttons during certain stages in react stepzilla

When working with React Stepzilla, I encountered an issue where I have five steps but need to hide the next button on the first step. Following different methods provided online such as: const steps = [ {name: 'Step 1', com ...

What is the best way to manage connection leaks in Node.js?

I developed a server application using Node.js. After executing lsof -p 10893 (where 10893 is the process ID of my Node.js app), I observed the following output: node 10893 root 19u IPv4 (num) 0t0 TCP ip-X.X.X.X->ip-X-X-X.X:45403 (ESTABLISHED ...

How can we protect against CSRF attacks?

My typical approach involves using AJAX to input data into a MYSQL database like this: $.ajax({ url: "writescript.php", type: "POST", data: { data : mydata,//this could be anything }, success: function (html) { //do something ...