- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
为了使用 WebRTC API
连接点对点通信,您需要实现信令。信令需要双向通信 channel 才能工作。 WebSockets
是双向通信 channel 。我想使用 WebSockets
来实现信令,但是,我不知道如何处理它。我在网上找到的所有内容都只是讨论了您可以使用的不同的两种方式 channel ,而不是提供有关如何使用它们的示例。
我在客户端使用 JavaScript
,在服务器端使用 Java
。那么,我将如何使用 WebSockets
实现信令?
最佳答案
这是我想出的方法。我还没有测试代码,所以,我不确定它是否有效。另外,我怀疑这是否有效。如果您有更好的解决方案,请查看我的代码中的问题,或任何建议,请随时详细说明。这背后的想法是让 WebSocket 服务器端点过滤消息并将它们发送给适当的用户。
首先,我使用预先确定的用户 ID 向客户端发送消息。 WebSocket 服务器端点只知道包含 session ID 的 session 对象(不能更改;没有设置方法)。为了链接 session ID 和用户 ID,我需要一个数据库表(比将其保存在内存中更可靠)。
然后,从客户端发送到 WebSocket 服务器端点的第一条消息将包含该用户的 ID。这将与 session ID 一起映射到数据库,客户端将被视为“已连接”。当然,这是在实际连接到 WebSocket 之后发生的。
现在,一旦“连接”,我们就可以向另一个用户发送(信号)消息,只要我们知道他们的用户 ID(我假设我们知道)。 WebSocket 服务器端点根据数据库检查接收者用户 ID 以找到他们的 session ID。一旦找到,就可以发送消息。
最后,在客户端,我们可以破译消息并将适当的消息发回(使用与上述相同的过程)。
因此,如前所述,我们需要一个用于客户端 session 和用户 ID 的数据库表。由于我将 Java 用于所有后端代码,因此我们将通过创建一个实体类来保存属性来使用 ORM(对象关系映射)。像这样:
@Entity
public class WebSocketUser {
@Id@GeneratedValue
private long id;
private long userId;
private long sessionId;
//constructors, getters and setters
}
现在,我们可以创建服务器端点类:
@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:
@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();
}
接下来,在 WebSocket Server Endpoint 的 onMessage 方法中,我们过滤消息。我选择以 JSON 格式发送消息。这使您可以轻松破译信息(我使用了 org.json 库)。 onMessage 方法:
@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 变量:
var signalingSocket = new WebSocket("/SignalingServerEndpoint"); //TODO need the full and correct path to the WebSocket
现在,对于将消息发送到“连接”到 WebSocket 服务器端点的方法:
function connect(){
var msg = {
"userId": userId
};
signalingSocket.send(JSON.stringify(msg));
最后,我们所拥有的只是客户端的 onMessage 方法(它将解密消息并可能将信息发送到其他客户端)和所有实际的信号代码(ICE 服务器、约束等)。我不会深入研究所有的信令工作,但有一个很好的教程 here.我希望这可以帮助其他面临类似问题的人。正如我所说,我还没有测试代码,所以我不确定它是否有效。另外,我非常怀疑这是否有效。但这至少是一个开始。
关于java - 使用 WebSockets 实现 WebRTC 信令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25019945/
很抱歉新手的问题,但是: 我最近才发现“=”运算符不只是处理对象/等等。值(value),也是引用。这很酷,但我认为这对变量来说是不一样的,它不会在存储整数或 float 的变量之间创建引用。后来我觉
我是一名优秀的程序员,十分优秀!