客户端到客户端的短消息

Posted

技术标签:

【中文标题】客户端到客户端的短消息【英文标题】:Client to client short messaging 【发布时间】:2019-04-08 15:48:26 【问题描述】:

我正在 android 中实现两个客户端之间的小型通信。目前我正在使用Firebase Realtime Database,它持有我所有的用户推送令牌。

我使用 Firebase Cloud Messaging 使用嵌入在我的代码中的 REST 将推送消息从一个发送到另一个。这不是很好的做法,因为我需要在应用程序中保存硬编码的服务器密钥。我考虑过使用 XMPP,但它对我的需要有点过分了。

我需要用户之间进行少量交流,以便一个人询问另一个人的位置并获得坐标作为回报。消息不需要保存在服务器上,它只是一次请求和响应。正如我之前所说,我目前正在为此使用 FCM。

您能否建议在没有 XMPP 的情况下更好的解决方案?

【问题讨论】:

你可以使用 SOCKET IO 您能否详细说明为什么不适合使用 Firebase 云消息传递 (FCM)?我有一个使用实时数据库来完成此任务的想法,但 FCM 似乎是首选方法。 【参考方案1】:

使用 Firebase 云消息传递似乎是更可取的方法。但是,如果这对您不起作用,我们可以利用实时数据库来执行此操作,尽管它不会是严格的客户端到客户端。

举个例子:假设我们有 2 个用户的 UID 分别为 user1user2。数据库的结构可以使每个用户在/requests/responses 节点下都有自己的列表:


  "requests": 
    "user1": ,
    "user2": 
  ,
  "responses": 
    "user1": ,
    "user2": 
  

user2想要请求user1的位置的场景中,客户端将遵循以下流程:

对于 Android,这将是这样的:

private FirebaseDatabase database = FirebaseDatabase.getInstance();
private FirebaseAuth auth = FirebaseAuth.getInstance();
private String myUserId;

private void setup() 
    if (auth.getCurrentUser() == null)  // User must be signed-in
        finish();
        return;
    

    myUserId = auth.getCurrentUser().getUid();

    DatabaseReference requestsRef = database.getReference("requests").child(myUserId);
    DatabaseReference responsesRef = database.getReference("responses").child(myUserId);

    requestsRef.addChildEventListener(new ChildEventListener() 
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) 
            handleRequest(dataSnapshot.getKey());
            dataSnapshot.getRef().removeValue(); // Delete the request once it's been handled
        
        // ...
    );

    responsesRef.addChildEventListener(new ChildEventListener() 
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) 
            String from = dataSnapshot.getKey();
            String coordinates = dataSnapshot.getValue(String.class);
            if (from != null && coordinates != null) handleResponse(from, coordinates);
            dataSnapshot.getRef().removeValue(); // Delete the response once it's been handled
        
        // ...
    );


private void handleResponse(String from, String coordinates) 
    Toast.makeText(this, String.format("User: %s is located at: %s", from, coordinates), Toast.LENGTH_SHORT).show();


private void handleRequest(String from) 
    Toast.makeText(this, String.format("User: %s wants to know our location", from), Toast.LENGTH_SHORT).show();
    sendResponse(from);


private void sendResponse(String to) 
    String myCoordinates = "37.4220° N, 122.0841° W"; // Example, this will need implementing
    database.getReference("/responses").child(to).child(myUserId).setValue(myCoordinates);


private void sendRequest(String to) 
    database.getReference("/requests").child(to).child(myUserId).setValue(true);

在此示例中,两个用户的客户端都将首先调用 setup() 以开始侦听请求和响应。

然后,要请求用户的坐标,请从一位客户端致电sendRequest()。另一个客户端将在handleRequest() 方法中接收此请求并将其坐标发送到数据库。最后,请求客户端将在handleResponse() 方法中收到此响应。

这可能不是你想要的,但它对我来说是一个有趣的练习,所以我还是想分享它。

【讨论】:

【参考方案2】:

SOCKET 非常简单,很多大公司都在使用它。

使用 Socket 客户端,如果您的应用程序中的换向将是 2 种方式,您可以启用发送和接收方法。

例如: 发送您的经纬度使用

String location = "123123,123123"
mSocket.emit("Update", location);

并且要接收其他用户的新位置,请在您的 OnCreate 内的代码下方放置:

mSocket.on("Update", GettingUpdate);
mSocket.connect();

然后在 GettingUpdate 方法中执行你的逻辑

private Emitter.Listener GettingUpdate= new Emitter.Listener() 
    @Override
    public void call(final Object.. args) 
        getActivity().runOnUiThread(new Runnable() 
            @Override
            public void run() 
                JSONObject data = (JSONObject) args[0];
                String location;
                try 
                    location= data.getString("location");
                 catch (JSONException e) 
                    return;
                

               Toast.makeText(getActivity(), message,Toast.LENGTH_LONG).show();

            
        );
    
;

你可以在documentation找到例子

Android 项目示例:Github

【讨论】:

【参考方案3】:

现在您可以使用 Firebase 实时数据库和云 Firestore 数据库,无需 FCM,您也将获得实时和离线

https://code.tutsplus.com/tutorials/how-to-create-an-android-chat-app-using-firebase--cms-27397

享受

【讨论】:

以上是关于客户端到客户端的短消息的主要内容,如果未能解决你的问题,请参考以下文章

graphql-java 错误数据(如扩展)被填充到客户端的“消息”字段中

java socket如何实现客户端与客户端的交互?

当收到新消息而不重新加载视图时,如何将来自 stomp 客户端的消息显示到视图中

从 Tomcat 9 到客户端的 Websocket 二进制消息拆分为 2 个或更多 tcp 数据包

谈消息总线客户端的多线程实现

如何用java相关的技术实现一个服务器到手机客户端的一个消息推送?