# @OnClose liefert Errors



## RezaScript (10. Jun 2019)

Hallo,

ich möchte einfach nur den Browser informieren, dass die Verbindung zwischen User und Server abgebrochen ist. 

Ich bekomme aber diese Fehlermeldung:


> 10-Jun-2019 02:49:30.547 SCHWERWIEGEND [http-nio-8080-exec-9] org.apache.tomcat.websocket.pojo.PojoEndpointBase.onClose Failed to call onClose method of POJO end point for POJO of type [ch.yourclick.zt.chat.ChatEndpoint]



Meine Methode sieht so aus:

```
@OnClose
public void handleClose(Session userSession) throws IOException {
    // Post the message
    for (Session user : users) {
        postMessage();

        Data data = new Data("message", currentTime, (String) userSession.getUserProperties().get("username"), "null", "null", "null");
        if (!Objects.requireNonNull(Database.getData("SELECT * FROM users WHERE username = '" + userSession.getUserProperties().get("username") + "'", this.user)).isEmpty()) {
            data = new Data("message", this.currentTime, (String) userSession.getUserProperties().get("username"), "null", "true", "null");
        }
        user.getBasicRemote().sendText(gson.toJson(data));
    }
    users.remove(userSession);
}
```

Meine gesamte Klasse sieht so aus:

```
package ch.yourclick.zt.chat;

import ch.yourclick.zt.Database;
import ch.yourclick.zt.Helper;
import com.google.gson.Gson;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;

@ServerEndpoint("/chat")
public class ChatEndpoint {
    private Session userSession;
    private String message;
    private HashMap<String, String> user;
    private String currentTime;
    private Gson gson = new Gson();

    private static Set<Session> users = Collections.synchronizedSet(new HashSet<>());

    @OnOpen
    public void handleOpen(Session userSession) {
        users.add(userSession);
    }

    @OnMessage
    public void handleMessage(String message, Session userSession) throws Exception {
        /* eventType: nickname */

        this.userSession = userSession;
        this.message = message;
        // Get the username
        if (userSession.getUserProperties().get("username") == null) {
            // Throw an error
            if (message.length() > 30) {
                Data data = new Data("nickname", "null", "null", "null", "null", "Nickname is too long");
                userSession.getBasicRemote().sendText(gson.toJson(data));
            }
            else {
                // User is good, let him in
                userSession.getUserProperties().put("username", message);
                postMessage();
                Data data = new Data("nickname", "null", (String) userSession.getUserProperties().get("username"), "null", "null", "null");
                if (!Objects.requireNonNull(Database.getData("SELECT * FROM users WHERE username = '" + userSession.getUserProperties().get("username") + "'", user)).isEmpty()) {
                    data = new Data("nickname", "null", (String) userSession.getUserProperties().get("username"), "null", "true", "null");
                }
                userSession.getBasicRemote().sendText(gson.toJson(data));
            }
        }
        else {
            /* eventType: message */

            // Post the message
            for (Session user : users) {
                postMessage();
                Data data = new Data("message", this.currentTime, (String) userSession.getUserProperties().get("username"), message, "null", "null");
                if (!Objects.requireNonNull(Database.getData("SELECT * FROM users WHERE username = '" + userSession.getUserProperties().get("username") + "'", this.user)).isEmpty()) {
                    data = new Data("message", this.currentTime, (String) userSession.getUserProperties().get("username"), message, "true", "null");
                }
                user.getBasicRemote().sendText(gson.toJson(data));
            }
        }
    }

    @OnClose
    public void handleClose(Session userSession) throws IOException {
        // Post the message
        for (Session user : users) {
            postMessage();

            Data data = new Data("message", currentTime, (String) userSession.getUserProperties().get("username"), "null", "null", "null");
            if (!Objects.requireNonNull(Database.getData("SELECT * FROM users WHERE username = '" + userSession.getUserProperties().get("username") + "'", this.user)).isEmpty()) {
                data = new Data("message", this.currentTime, (String) userSession.getUserProperties().get("username"), "null", "true", "null");
            }
            user.getBasicRemote().sendText(gson.toJson(data));
        }
        users.remove(userSession);
    }

    @OnError
    public void handleError(Throwable t) {
        t.printStackTrace();
    }

    private void postMessage() {
        Helper helper = new Helper();
        this.currentTime = helper.getTheDate("HH:mm:ss");

        HashMap<String, String> user = new HashMap<>();
        user.put("string", "username");
        this.user = user;
    }
}
```
Was mache ich falsch?


----------



## mrBrown (10. Jun 2019)

Du versuchst aktuell auch den User, der die Verbindung geschlossen hat, über eben diese Verbindung darüber zu informieren.

Lösch die Session aus der Liste, bevor du drüber iterierst 


Die Fehlermeldung sollte btw noch weiter gehen, und einen wirklichen Grund enthalten. Falls obiges das Problem nicht löst, zeig die noch mal.


----------



## RezaScript (10. Jun 2019)

Hmm, ich habe jetzt einfach `users.remove(userSession);` zuoberst in der Methode gesetzt. Scheint nun zu funktionieren und ich bekomme auch keine Fehlermeldungen mehr. Komisch, weil ich schon daran gedacht hatte und den Code schon mal oben gesetzt hatte, um es mal auszuprobieren aber wahrscheinlich hatte es deshalb nicht geklappt, weil ich ein redeploy gemacht hatte und den Server nicht neu gestartet habe. Bei redeploy werden die Sessions ja nicht gelöscht


----------

