如何在不同进程中从远程服务向 IPC 客户端发送数据

Posted

技术标签:

【中文标题】如何在不同进程中从远程服务向 IPC 客户端发送数据【英文标题】:How to send data to an IPC client from a remote service in different processes 【发布时间】:2020-12-03 13:47:27 【问题描述】:

有一个IPC客户端和一个IPC服务器(远程服务)属于不同的进程。绑定到远程服务后,我需要开始连续向客户端发送数据。我可以绑定到服务并从客户端调用 AIDL 方法,但我找不到将数据从远程服务发送到客户端的方法。

【问题讨论】:

【参考方案1】:

这可以通过在 AIDL 中使用远程回调来实现。服务器实现了一个 AIDL,它允许客户端在绑定到服务后注册一个远程回调(回调也是一个 AIDL)。然后服务器可以在需要时调用远程回调以向客户端发送数据。请参阅下面来自 android API 演示的代码 sn-ps。

IRemoteService.aidl

interface IRemoteService 
/**
 * Often you want to allow a service to call back to its clients.
 * This shows how to do so, by registering a callback interface with
 * the service.
 */
void registerCallback(IRemoteServiceCallback cb);

/**
 * Remove a previously registered callback interface.
 */
void unregisterCallback(IRemoteServiceCallback cb);

IRemoteServiceCallback.aidl

oneway interface IRemoteServiceCallback 
/**
 * Called when the service has a new value for you.
 */
void valueChanged(int value);

客户端和服务器端代码都可以在RemoteService.java看到

注册远程回调的客户端代码

        private ServiceConnection mConnection = new ServiceConnection() 
        public void onServiceConnected(ComponentName className,
                IBinder service) 
            // This is called when the connection with the service has been
            // established, giving us the service object we can use to
            // interact with the service.  We are communicating with our
            // service through an IDL interface, so get a client-side
            // representation of that from the raw service object.
            mService = IRemoteService.Stub.asInterface(service);
            mKillButton.setEnabled(true);
            mCallbackText.setText("Attached.");

            // We want to monitor the service for as long as we are
            // connected to it.
            try 
                mService.registerCallback(mCallback);
             catch (RemoteException e) 
                // In this case the service has crashed before we could even
                // do anything with it; we can count on soon being
                // disconnected (and then reconnected if it can be restarted)
                // so there is no need to do anything here.
            

调用客户端远程回调的服务器端代码

               `// Broadcast to all clients the new value.
                final int N = mCallbacks.beginBroadcast();
                for (int i=0; i<N; i++) 
                    try 
                        mCallbacks.getBroadcastItem(i).valueChanged(value);
                     catch (RemoteException e) 
                        // The RemoteCallbackList will take care of removing
                        // the dead object for us.
                    
                
                mCallbacks.finishBroadcast();`
                

【讨论】:

以上是关于如何在不同进程中从远程服务向 IPC 客户端发送数据的主要内容,如果未能解决你的问题,请参考以下文章

客户端进程(在带有aidl的android IPC中)如何知道远程服务器类?

简单的 Linux IPC 问题

如何在 Qt 中从服务器向连接的客户端发送消息

如何在 Web 套接字中从服务器向客户端发送消息

.NET IPC 没有服务中介

C中的进程间通信