Frage

Um Peer-to-Peer für die Kommunikation mit dem zu verbinden WebRTC API, müssen Sie die Signalisierung implementieren.Die Signalisierung benötigt einen bidirektionalen Kommunikationskanal, um zu funktionieren. WebSockets sind ein Zwei-Wege-Kommunikationskanal.Ich möchte verwenden WebSockets um die Signalisierung zu implementieren, habe ich jedoch keine Ahnung, wie ich das angehen soll.Alles, was ich online gefunden habe, beschreibt nur die verschiedenen Zwei-Wege-Kanäle, die Sie verwenden können, anstatt ein Beispiel für deren Verwendung zu geben.

Ich benutze JavaScript für die Kundenseite und Java für die Serverseite.Also, wie würde ich die Signalisierung implementieren mit WebSockets?

War es hilfreich?

Lösung

Hier ist ein Weg, wie ich herausgefunden habe, wie das geht.Ich habe den Code noch nicht getestet, daher bin ich mir nicht sicher, ob er funktioniert.Ich bin auch skeptisch, ob das effizient sein wird.Wenn Sie eine bessere Lösung haben, sehen Sie ein Problem in meinem Code oder einen Ratschlag, den Sie gerne erläutern können.Die Idee dahinter ist, dass der WebSocket-Server-Endpunkt Nachrichten filtert und an den entsprechenden Benutzer sendet.

  • Zuerst sende ich Nachrichten mit einer vorgegebenen Benutzer-ID an Clients.Dem WebSocket-Server-Endpunkt sind nur Sitzungsobjekte bekannt, die Sitzungs-IDs enthalten (die nicht geändert werden können;keine festgelegte Methode).Um die Sitzungs-ID und die Benutzer-ID zu verknüpfen, benötige ich eine Datenbanktabelle (viel zuverlässiger als diese im Speicher zu behalten).

  • Dann enthält die erste Nachricht, die vom Client an den WebSocket-Serverendpunkt gesendet wird, die ID dieses Benutzers.Dies wird zusammen mit der Sitzungs-ID der Datenbank zugeordnet und der Client wird als "verbunden" betrachtet.Dies geschieht natürlich nach dem tatsächlichen Herstellen einer Verbindung zum WebSocket.

  • Sobald wir "verbunden" sind, können wir (Signal-) Nachrichten an einen anderen Benutzer senden, solange wir dessen Benutzer-ID kennen (was ich annehme).Der WebSocket-Serverendpunkt vergleicht die Benutzer-ID des Empfängers mit der Datenbank, um ihre Sitzungs-ID zu ermitteln.Einmal gefunden, kann die Nachricht gesendet werden.

  • Schließlich können wir auf der Clientseite die Nachricht entschlüsseln und die entsprechende Nachricht zurücksenden (mit dem gleichen Verfahren wie oben).

Wie bereits erwähnt, benötigen wir also eine Datenbanktabelle für die Client-Sitzung und die Benutzer-IDs.Da ich Java für den gesamten Back-End-Code verwende, werden wir ORM (Object Relational Mapping) verwenden, indem wir eine Entitätsklasse erstellen, die die Attribute enthält.So etwas in der Art:

    @Entity
    public class WebSocketUser {
        @Id@GeneratedValue
        private long id;
        private long userId;
        private long sessionId;

        //constructors, getters and setters
    }

Jetzt können wir die Server-Endpunktklasse erstellen:

    @ServerEndpoint("/SignalingServerEndpoint")
    public class SignalingServerEndpoint {
        //these class variables will be useful for 
        //access to the database and such
        private EntityManagerFactory emf;
        private EntityManager em;
        private EntityTransaction tx;
        private TypedQuery<WebsocketUser> query;
        private WebsocketUser wsu;

Da wir uns nicht in einer EJB befinden, müssen wir den Entitätsmanager wie in einer anwendungsverwalteten Umgebung steuern.Fügen Sie dem Websocket die Methoden onOpen und onClose hinzu:

    @OnOpen
    public void open(Session session, Endpoint config){
        emf = Persistence.createEntityManagerFactory(""); //TODO add persistence unit reference here
        em = emf.createEntityManager();
        tx = em.getTransaction();
    }

    @OnClose
    public void close(Session session, CloseReason reason){
        //if session is closing and information still exists in the database; remove it
        if (!wsu.equals(null)){
            tx.begin();
            em.remove(wsu);
            tx.commit();
        }
        em.close();
        emf.close();
    }

Als nächstes filtern wir in der onMessage-Methode im WebSocket-Server-Endpunkt die Nachrichten.Ich habe mich dafür entschieden, Nachrichten im JSON-Format zu senden.Auf diese Weise können Sie die Informationen leicht entschlüsseln (ich habe die org.json-Bibliothek).Die onMessage-Methode:

    @OnMessage
    public void message(Session session, String msg){
        try {
            JSONObject obj = new JSONObject(msg);
            if (!obj.has("toUserId")){
                //adding user to the database, so they can access their session ID with their user ID
                WebsocketUser wsu = new WebsocketUser(obj.getLong("userId"), session.getId());
                tx.begin();
                em.persist(wsu);
                tx.commit();
            }else if (obj.has("toUserId")){
                //message to be sent to the user with the specified user ID
                //get session ID from database
                query = em.createQuery("SELECT u FROM WebsocketUser u WHERE u.userId = " + obj.getLong("toUserId"), WebsocketUser.class);
                wsu = (WebsocketUser) query.getSingleResult();
                Set<Session> sessions = session.getOpenSessions();
                for (Iterator<Session> i = sessions.iterator(); i.hasNext();){
                    Session s = i.next();
                    if (s.getId().equals(wsu.getSessionId())){
                        s.getAsyncRemote().sendText(obj.getString("message"));
                        break;
                    }
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

Schließlich haben wir nur noch die Clientseite (Javascript) übrig.Erstellen Sie die WebSocket-Variable:

    var signalingSocket = new WebSocket("/SignalingServerEndpoint"); //TODO need the full and correct path to the WebSocket

Nun zu der Methode, die die Nachricht an "Verbinden" mit dem WebSocket-Server-Endpunkt sendet:

    function connect(){
        var msg = {
            "userId": userId
        };
        signalingSocket.send(JSON.stringify(msg));

Und schließlich haben wir nur die onMessage-Methode auf der Clientseite (die die Nachricht entschlüsselt und möglicherweise Informationen an den anderen Client sendet) und den gesamten eigentlichen Signalisierungscode (ICE-Server, Einschränkungen usw.).).Ich werde nicht auf die gesamte Signalisierungsarbeit eingehen, aber es gibt ein gutes Tutorial hier. Ich hoffe, das hilft jedem anderen, der mit einem ähnlichen Problem konfrontiert ist.Wie gesagt, ich habe den Code nicht getestet, daher bin ich mir nicht sicher, ob er funktioniert.Ich bin auch sehr skeptisch, ob das überhaupt effizient sein wird.Aber es ist zumindest ein Anfang.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top