首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用WebRTC实现WebSockets信令

用WebRTC实现WebSockets信令
EN

Stack Overflow用户
提问于 2014-07-29 16:08:13
回答 1查看 3.5K关注 0票数 5

为了使用WebRTC API连接对等通信,您需要实现信令。信令需要双向通信通道才能工作。WebSockets是双向通信通道。我想使用WebSockets来实现信令,但是,我不知道如何处理这个问题。我在网上找到的所有东西都只是讨论了你可以使用的不同的双向通道,而不是提供一个如何使用它们的例子。

我在客户端使用JavaScript,服务器端使用Java。那么,我将如何使用WebSockets实现信令呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-04 15:02:11

我想出了一个办法。我还没有测试代码,所以,我不确定它是否有效。而且,我怀疑这是否有效。如果您有更好的解决方案,请在我的代码中看到一个问题,或者任何建议都可以详细说明。这背后的想法是让WebSocket服务器端点过滤器通过消息并将它们发送给适当的用户。

  • 首先,我使用预定的用户id向客户端发送消息。WebSocket服务器端点只知道包含会话id(不能更改;没有set方法)的会话对象。为了链接会话id和用户id,我需要一个数据库表(比将其保存在内存中要可靠得多)。
  • 然后,从客户端发送到WebSocket服务器端点的第一条消息将包含该用户的id。这将与会话id一起映射到数据库,客户端将被视为“连接”。当然,这是在实际连接到WebSocket之后发生的。
  • 现在,一旦“连接”,我们就可以向另一个用户发送(信令)消息,只要我们知道他们的用户id (我假设我们知道)。WebSocket服务器端点根据数据库检查收件人用户id,以找到他们的会话id。一旦找到,就可以发送消息。
  • 最后,在客户端,我们可以对消息进行解密,并将适当的消息发回(使用上述相同的过程)。

因此,如前所述,我们将需要一个用于客户端会话和用户id的数据库表,因为我在所有后端代码中使用Java,我们将通过创建一个实体类来保存这些属性,从而使用ORM (对象关系映射)。就像这样:

代码语言:javascript
运行
复制
    @Entity
    public class WebSocketUser {
        @Id@GeneratedValue
        private long id;
        private long userId;
        private long sessionId;

        //constructors, getters and setters
    }

现在,我们可以使类:

代码语言:javascript
运行
复制
    @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;

由于我们不是在EJB中,所以我们必须像在应用程序托管环境中一样控制实体管理器。将onOpen和onClose方法添加到Websocket中:

代码语言:javascript
运行
复制
    @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();
    }

接下来,在onMessage服务器端点中的WebSocket方法中,我们对消息进行过滤。我选择以JSON格式发送消息。这允许您轻松地解密信息(我使用了org.json库)。onMessage方法:

代码语言:javascript
运行
复制
    @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();
        }
    }

最后,我们只剩下客户端(javascript)。创建WebSocket变量:

代码语言:javascript
运行
复制
    var signalingSocket = new WebSocket("/SignalingServerEndpoint"); //TODO need the full and correct path to the WebSocket

现在,对于将消息“连接”到WebSocket服务器终结点的方法:

代码语言:javascript
运行
复制
    function connect(){
        var msg = {
            "userId": userId
        };
        signalingSocket.send(JSON.stringify(msg));

最后,我们所拥有的只是客户端的onMessage方法(它将解密消息并可能向另一个客户端发送信息)和所有实际的信令代码(ICE服务器、约束等)。我不会进入所有的信令工作,但有一个很好的教程这里。,我希望这能帮助其他面临类似问题的人。正如我所说的,我还没有测试代码,所以我不确定它是否能工作。此外,我非常怀疑这是否会有效率。但这至少是一个开始。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25019945

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档