Search code examples
javascriptangularjswebsocketjava-ee-7

Websocket Javascript client onmessage won't fire


I'm trying to learn websocket. I started sending simple string between peers and everything was fine. Now I'm trying to send Object to my client but the onmessage function never fires. Here is the code:

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>

The server gets the JSON object from the client correctly, but when it sends some Position object back the client, the onmessage function won't fire. I can see the Encoder is working as it returns strings like this:

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

I see the websocket carry the messages:

Position sent

but my javascript onmessage function always stay silent. I also implemented an onerror function but I can't get any feedback from it too. I'm using wildfly-8.0.0.Final.

Update: I implement a java websocket client. This client receive websocket frame sent by the server. Is my AngularJS client wrong?


Solution

  • I found what was wrong. In my javascript client I assigned a function to an undefined object. Here:

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

    service.ws.onmessage was undefined, that's why onmessage function never fire. I change my angular factory in this way:

    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;
    });