Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web Socket Problem with Javascript and Java - Uncaught DOMException: An attempt was made to use an object that is not, or is no longer, usable

I'm trying to make a web socket connection between js and java, but I get this answer:
Uncaught DOMException: An attempt was made to use an object that is not, or is no longer, usable
I did it based in some samples on internet. Someone have some idea what can it be?
Project Name is Teste-1


JS Code

var socket = null;
function init(){
    socket = new WebSocket("wss://localhost:8080/Teste-1/task");    
    socket.onmessage = onMessage;
    
}

function onMessage(event){
     var task = JSON.parse(event.data);
     if(task.action === "add"){
         document.getElementById("point").innerHTML += event.data;
     }                
}

function teste() {
    var action = {
        action: "add",
        name: "Test",
        description: "This is just a test"
    };
    socket.send(JSON.stringify(action));
}
window.onload = init;

HTML Code

<html>
    <head>
        <title>Test</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        
    </head>
    <body>
        <button onclick="teste()">Teste</button>
        <div id="point"></div>
        <script src="websocket.js"></script>
    </body>
</html>

JAVA Codes

public class Task implements Serializable{
    private static final long serialVersionUID = 1L;
    private String name;
    private String description;
    
    public Task(){}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
 }
@ServerEndpoint(value="/task")
public class TaskSocket {
    @Inject
    private TaskSessionHandler handler;
    
    @OnOpen
    public void open(Session session){
        handler.addSession(session);
    }
    
    @OnClose
    public void close(Session session){
        handler.removeSession(session);
    }
    
    @OnError
    public void onError(Throwable error){
        Logger.getLogger(TaskSocket.class.getName()).log(Level.SEVERE, null, error);
    }
    
    @OnMessage
    public void handleMessage(String message, Session session) {
        try (JsonReader reader = Json.createReader(new StringReader(message))) {
            JsonObject jsonMessage = reader.readObject();

            if ("add".equals(jsonMessage.getString("action"))) {
                Task task = new Task();
                task.setName(jsonMessage.getString("name"));
                task.setDescription(jsonMessage.getString("description"));
                
                handler.addTask(task);
            }

            
        }
    }
}


@ApplicationScoped
public class TaskSessionHandler {
    //Each client connected to the application has its own session.
    private final Set<Session> sessions = new HashSet<>();
    private final Set<Task> tasks = new HashSet<>();
    
    public void addSession(Session session) {
        sessions.add(session);
        for(Task task : tasks){
            JsonObject addMessage = createJSON(task);
            sendToSession(session, addMessage);
        }
    }

    public void removeSession(Session session) {
        sessions.remove(session);
    }
    
    public List<Task> getTasks(){
        List<Task> list = new ArrayList<Task>(tasks);
        return list;
    }
    
    public void addTask(Task e){
        tasks.add(e);
        JsonObject message = this.createJSON(e);
        sendToAllConnectedSessions(message);
    }
    
    private JsonObject createJSON(Task task){
        JsonProvider provider = JsonProvider.provider();
        JsonObject message = provider.createObjectBuilder()
                .add("action", "add")
                .add("name",task.getName())
                .add("description",task.getDescription()).build();
        return message;
    }
    
     private void sendToAllConnectedSessions(JsonObject message) {
        for (Session session : sessions) {
            sendToSession(session, message);
        }
    }
    
    private void sendToSession(Session session, JsonObject message) {
        try {
            session.getBasicRemote().sendText(message.toString());
        } catch (IOException ex) {
            sessions.remove(session);
            Logger.getLogger(TaskSessionHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
}
like image 672
rtk Avatar asked Sep 03 '25 06:09

rtk


1 Answers

I got the same error message due to the websocket.send() being executed before the connection to the webSocket server was established and open.

My contribution would be the advice to make sure messages aren't sent until the connection is open, so that the server actually can receive them.

I cannot tell whether that was the problem in the question asked though. However I faced a very similar problem and ended up here, and wanted to share what worked for me.

In my case the code that didn't work looked like this:

const exampleSocket = new WebSocket('wws://example')

exampleSocket.onopen = function (event) {
  console.log('connection is open!')
}

exampleSocket.send(JSON.stringify(msg))

exampleSocket.onmessage = function (event) {
  console.log('message event data looks like this: ', event.data)
}

What worked was moving the code that sent a message into the onopen callback function.

const exampleSocket = new WebSocket('wws://example')
    
    exampleSocket.onopen = function (event) {
      console.log('connection is open!')
      exampleSocket.send(JSON.stringify(msg))             // <- this is the change
    }
    
    exampleSocket.onmessage = function (event) {
      console.log('message event data looks like this: ', event.data)
    }

Sidenote: the readyState property of websocket could be useful when dealing with making sure the server is ready to receive messages.

If it is 1, it means connection is open, so it could be used like this:

if (exampleSocket.readyState  === 1) {
     console.log("It is safe to send messages now")
}
like image 157
Alvanius Avatar answered Sep 04 '25 20:09

Alvanius