Cómo usar el señalizador en Android

signalR integrar signalR en la aplicación de android pero no signalR suerte. He estado buscando varios enlaces, pero ninguno de ellos proporciona información adecuada sobre la implementación.

Tengo las siguientes preguntas.

  • SignalR integración de SignalR debe hacerse dentro del Servicio / Servicio de Intento?
  • Si queremos recibir una respuesta a través del mismo método de llamada, ¿cómo obtenerlo?

He agregado tres bibliotecas, es decir, signalr android , signalr client y gson pero no gson entender cómo funciona el código, no hay documentación adecuada disponible para comprender el código.

Algunas de las preguntas formuladas pero no mucha información

SignalR en Android Studio Imposible implementar chat p2p usando SignalR en Android

Si alguien tiene experiencia en señal para aplicaciones nativas, sería muy útil para mí.

Actualizar

  public class SignalRService extends Service { private static final String TAG = "Service"; private HubConnection mHubConnection; private HubProxy mHubProxy; private Handler mHandler; // to display Toast message private final IBinder mBinder = new LocalBinder(); private SharedPreferences sp; @Override public void onCreate() { super.onCreate(); Utility.showLog(TAG, "Service Created"); sp = getSharedPreferences(Utility.SHARED_PREFS, MODE_PRIVATE); mHandler = new Handler(Looper.myLooper()); } @Override public int onStartCommand(Intent intent, int flags, int startId) { int result = super.onStartCommand(intent, flags, startId); startSignalR(); return result; } @Override public IBinder onBind(Intent intent) { startSignalR(); return mBinder; } /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ public class LocalBinder extends Binder { public SignalRService getService() { // Return this instance of SignalRService so clients can call public methods return SignalRService.this; } } /** * method for clients (activities) */ public void sendMessage() { String SERVER_METHOD_SEND = "iAmAvailable"; final String string = new String(); mHubProxy.invoke(new String(), SERVER_METHOD_SEND, sp.getString("user_id", null), sp.getString("pass", null), "TransMedic").done(new Action() { @Override public void run(Object o) throws Exception { Utility.showLog(TAG, o.toString()); } }).onError(new ErrorCallback() { @Override public void onError(Throwable throwable) { } }); } private void startSignalR() { Platform.loadPlatformComponent(new AndroidPlatformComponent()); String serverUrl = "http://transit.alwaysaware.org/signalr"; mHubConnection = new HubConnection(serverUrl); String SERVER_HUB_CHAT = "ChatHub"; mHubProxy = mHubConnection.createHubProxy(SERVER_HUB_CHAT); ClientTransport clientTransport = new ServerSentEventsTransport(mHubConnection.getLogger()); SignalRFuture signalRFuture = mHubConnection.start(clientTransport); try { signalRFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); return; } sendMessage(); } @Override public void onDestroy() { mHubConnection.stop(); super.onDestroy(); } } 

ACTUALIZACIÓN 2018:

Si está utilizando SignalR.net Core, use esta biblioteca, de lo contrario, obtendrá un error de conexión.

LADO DEL SERVIDOR:

El siguiente es mi código de muestra del lado del servidor, puede prestar atención a public void Send(string message) y public void SendChatMessage(string to, string message) .

  • Aplicación del lado del servidor: public void SendChatMessage (string to, string message)

    • Aplicación cliente de Android: mHubProxy.invoke (“SendChatMessage”, receiverName, message);
  • Aplicación del lado del servidor: public void Send (mensaje de cadena)

    • Aplicación cliente de Android: mHubProxy.invoke (“Enviar”, mensaje);
 namespace SignalRDemo { public class ChatHub : Hub { private static ConcurrentDictionary FromUsers = new ConcurrentDictionary(); //  private static ConcurrentDictionary ToUsers = new ConcurrentDictionary(); //  private string userName = ""; public override Task OnConnected() { DoConnect(); Clients.AllExcept(Context.ConnectionId).broadcastMessage(new ChatMessage() { UserName = userName, Message = "I'm Online" }); return base.OnConnected(); } public override Task OnDisconnected(bool stopCalled) { if (stopCalled) // Client explicitly closed the connection { string id = Context.ConnectionId; FromUsers.TryRemove(id, out userName); ToUsers.TryRemove(userName, out id); Clients.AllExcept(Context.ConnectionId).broadcastMessage(new ChatMessage() { UserName = userName, Message = "I'm Offline" }); } else // Client timed out { // Do nothing here... // FromUsers.TryGetValue(Context.ConnectionId, out userName); // Clients.AllExcept(Context.ConnectionId).broadcastMessage(new ChatMessage() { UserName = userName, Message = "I'm Offline By TimeOut"}); } return base.OnDisconnected(stopCalled); } public override Task OnReconnected() { DoConnect(); Clients.AllExcept(Context.ConnectionId).broadcastMessage(new ChatMessage() { UserName = userName, Message = "I'm Online Again" }); return base.OnReconnected(); } private void DoConnect() { userName = Context.Request.Headers["User-Name"]; if (userName == null || userName.Length == 0) { userName = Context.QueryString["User-Name"]; // for javascript clients } FromUsers.TryAdd(Context.ConnectionId, userName); String oldId; // for case: disconnected from Client ToUsers.TryRemove(userName, out oldId); ToUsers.TryAdd(userName, Context.ConnectionId); } public void Send(string message) { // Call the broadcastMessage method to update clients. string fromUser; FromUsers.TryGetValue(Context.ConnectionId, out fromUser); Clients.AllExcept(Context.ConnectionId).broadcastMessage(new ChatMessage() { UserName = fromUser, Message = message }); } public void SendChatMessage(string to, string message) { FromUsers.TryGetValue(Context.ConnectionId, out userName); string receiver_ConnectionId; ToUsers.TryGetValue(to, out receiver_ConnectionId); if (receiver_ConnectionId != null && receiver_ConnectionId.Length > 0) { Clients.Client(receiver_ConnectionId).broadcastMessage(new ChatMessage() { UserName = userName, Message = message }); } } } public class ChatMessage { public string UserName { get; set; } public string Message { get; set; } } } 

LADO DEL CLIENTE:

Si no ha leído mi respuesta en la siguiente pregunta:

Integración de SignalR en android studio

Entonces, aquí está mi código básico de trabajo:

 public class SignalRService extends Service { private HubConnection mHubConnection; private HubProxy mHubProxy; private Handler mHandler; // to display Toast message private final IBinder mBinder = new LocalBinder(); // Binder given to clients public SignalRService() { } @Override public void onCreate() { super.onCreate(); mHandler = new Handler(Looper.getMainLooper()); } @Override public int onStartCommand(Intent intent, int flags, int startId) { int result = super.onStartCommand(intent, flags, startId); startSignalR(); return result; } @Override public void onDestroy() { mHubConnection.stop(); super.onDestroy(); } @Override public IBinder onBind(Intent intent) { // Return the communication channel to the service. startSignalR(); return mBinder; } /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ public class LocalBinder extends Binder { public SignalRService getService() { // Return this instance of SignalRService so clients can call public methods return SignalRService.this; } } /** * method for clients (activities) */ public void sendMessage(String message) { String SERVER_METHOD_SEND = "Send"; mHubProxy.invoke(SERVER_METHOD_SEND, message); } private void startSignalR() { Platform.loadPlatformComponent(new AndroidPlatformComponent()); Credentials credentials = new Credentials() { @Override public void prepareRequest(Request request) { request.addHeader("User-Name", "BNK"); } }; String serverUrl = "http://192.168.1.100"; mHubConnection = new HubConnection(serverUrl); mHubConnection.setCredentials(credentials); String SERVER_HUB_CHAT = "ChatHub"; mHubProxy = mHubConnection.createHubProxy(SERVER_HUB_CHAT); ClientTransport clientTransport = new ServerSentEventsTransport(mHubConnection.getLogger()); SignalRFuture signalRFuture = mHubConnection.start(clientTransport); try { signalRFuture.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); return; } String HELLO_MSG = "Hello from Android!"; sendMessage(HELLO_MSG); String CLIENT_METHOD_BROADAST_MESSAGE = "broadcastMessage"; mHubProxy.on(CLIENT_METHOD_BROADAST_MESSAGE, new SubscriptionHandler1() { @Override public void run(final CustomMessage msg) { final String finalMsg = msg.UserName + " says " + msg.Message; // display Toast message mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), finalMsg, Toast.LENGTH_SHORT).show(); } }); } } , CustomMessage.class); } } 

Actividad:

 public class MainActivity extends AppCompatActivity { private final Context mContext = this; private SignalRService mService; private boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(); intent.setClass(mContext, SignalRService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { // Unbind from the service if (mBound) { unbindService(mConnection); mBound = false; } super.onStop(); } public void sendMessage(View view) { if (mBound) { // Call a method from the SignalRService. // However, if this call were something that might hang, then this request should // occur in a separate thread to avoid slowing down the activity performance. EditText editText = (EditText) findViewById(R.id.edit_message); if (editText != null && editText.getText().length() > 0) { String message = editText.getText().toString(); mService.sendMessage(message); } } } /** * Defines callbacks for service binding, passed to bindService() */ private final ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to SignalRService, cast the IBinder and get SignalRService instance SignalRService.LocalBinder binder = (SignalRService.LocalBinder) service; mService = binder.getService(); mBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mBound = false; } }; } 

Clase CustomMessage:

 public class CustomMessage { public String UserName; public String Message; } 

También puede ver mi proyecto de ejemplo de cliente en este enlace de GitHub


ACTUALIZAR PARA LA RESPUESTA DE INVOCAR:

Acabo de agregar nuevos métodos de muestra:

Lado del servidor:

 public string iAmAvailable(string username, string password, string message) { return "BNK Response for testing Android INVOKE"; } 

Lado del cliente:

 mHubProxy.invoke(String.class, "iAmAvailable", "username", "password", "TransMedic").done(new Action() { @Override public void run(String s) throws Exception { Log.w("SimpleSignalR", s); } }).onError(new ErrorCallback() { @Override public void onError(Throwable throwable) { Log.e("SimpleSignalR", throwable.toString()); } }); 

Y aquí está la captura de pantalla:

Respuesta a la señal de SignalR de Android

Este trabajo para mí: fuente completa Android (cliente) y servidor GitHub

Diapositiva del servidor Si un argumento debe usar esta interfaz SubscriptionHandler1 si dos argumentos deben usar este interfaceSubscriptionHandler2, …

Muestra para dos argumentos como:

Diapositiva del servidor:

 using Microsoft.AspNet.SignalR; namespace SignalRChat { public class ChatHub : Hub { public void Send(string name, string message) { // Two argument must use this interfaceSubscriptionHandler2 . Clients.All.broadcastMessage(name, message); } } } 

Diapositiva del cliente:

 mHubProxy.on(CLIENT_METHOD_BROADAST_MESSAGE, new SubscriptionHandler2() { @Override public void run(final String name,final String msg) { final String finalMsg = msg.toString(); // display Toast message mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), finalMsg, Toast.LENGTH_SHORT).show(); } }); } } , String.class,String.class); 

Para atrapar todo el mensaje puede usar esto:

 mHubConnection.received(new MessageReceivedHandler() { @Override public void onMessageReceived(final JsonElement json) { Log.e("onMessageReceived ", json.toString()); mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), json.toString(), Toast.LENGTH_SHORT).show(); } }); } }); 

Para aquellos que están implementando el cliente de señalR en android y la respuesta dada aquí no ayuda a recibir los mensajes, puede revisar esta respuesta por medio de rejnev .

La respuesta implementa un método diferente connection.received () que es capaz de recibir devoluciones de mensajes del servidor en mi caso.