Android WebSocket实践 |
您所在的位置:网站首页 › websocket安卓客户端工具 › Android WebSocket实践 |
既生HTTP何生WebSockt
与服务端交互的协议中,HTTP只能被动接收客户端请求,然后响应。而WebSocket在客户端与服务端建立连接以后,服务端可以主动发消息给客户端。这就是WebSocket的特点。 应用因为服务端可以主动发消息的特性,WebSocket在以下场景使用非常多: 1、推送 2、聊天室 3、开发工具 4... 大部分功能依赖于产品的业务,投入使用可能比较困难,而开发工具是开发人员可以肆意发挥的地方! ReactNative中WebSocket的使用ReactNative开发过程中,pc端可以控制android端重新加载、打印堆栈等等。这些的实现都依赖于WebSocket。 com.facebook.react.packagerconnection.ReconnectingWebSocket实现了WebSocket的连接,使用了okhttp。 final public class ReconnectingWebSocket extends WebSocketListener { public ReconnectingWebSocket( String url, MessageCallback messageCallback, ConnectionCallback connectionCallback) { super(); mUrl = url; mMessageCallback = messageCallback; mConnectionCallback = connectionCallback; mHandler = new Handler(Looper.getMainLooper()); } public void connect() { if (mClosed) { throw new IllegalStateException("Can't connect closed client"); } OkHttpClient httpClient = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .readTimeout(0, TimeUnit.MINUTES) // Disable timeouts for read .build(); Request request = new Request.Builder().url(mUrl).build(); httpClient.newWebSocket(request, this); } }JSPackagerClient包装了ReconnectingWebSocket,在onMessage回调处分发服务端下发的命令: final public class JSPackagerClient implements ReconnectingWebSocket.MessageCallback { private ReconnectingWebSocket mWebSocket; public JSPackagerClient( String clientId, PackagerConnectionSettings settings, Map requestHandlers, @Nullable ReconnectingWebSocket.ConnectionCallback connectionCallback) { super(); Uri.Builder builder = new Uri.Builder(); builder.scheme("ws") .encodedAuthority(settings.getDebugServerHost()) .appendPath("message") .appendQueryParameter("device", AndroidInfoHelpers.getFriendlyDeviceName()) .appendQueryParameter("app", settings.getPackageName()) .appendQueryParameter("clientid", clientId); String url = builder.build().toString(); mWebSocket = new ReconnectingWebSocket(url, this, connectionCallback); mRequestHandlers = requestHandlers; } @Override public void onMessage(String text) { try { JSONObject message = new JSONObject(text); int version = message.optInt("version"); String method = message.optString("method"); Object id = message.opt("id"); Object params = message.opt("params"); if (version != PROTOCOL_VERSION) { FLog.e( TAG, "Message with incompatible or missing version of protocol received: " + version); return; } if (method == null) { abortOnMessage(id, "No method provided"); return; } RequestHandler handler = mRequestHandlers.get(method); if (handler == null) { abortOnMessage(id, "No request handler for method: " + method); return; } if (id == null) { handler.onNotification(params); } else { handler.onRequest(params, new ResponderImpl(id)); } } catch (Exception e) { FLog.e(TAG, "Handling the message failed", e); } } }命令的具体执行在RequestHandler。注入RequestHandler的时机在DevServerHelper#openPackagerConnection public void openPackagerConnection( final String clientId, final PackagerCommandListener commandListener) { if (mPackagerClient != null) { FLog.w(ReactConstants.TAG, "Packager connection already open, nooping."); return; } new AsyncTask() { @Override protected Void doInBackground(Void... backgroundParams) { Map handlers = new HashMap(); handlers.put("reload", new NotificationOnlyHandler() { @Override public void onNotification(@Nullable Object params) { commandListener.onPackagerReloadCommand(); } }); handlers.put("devMenu", new NotificationOnlyHandler() { @Override public void onNotification(@Nullable Object params) { commandListener.onPackagerDevMenuCommand(); } }); handlers.put("captureHeap", new RequestOnlyHandler() { @Override public void onRequest(@Nullable Object params, Responder responder) { commandListener.onCaptureHeapCommand(responder); } }); handlers.putAll(new FileIoHandler().handlers()); ConnectionCallback onPackagerConnectedCallback = new ConnectionCallback() { @Override public void onConnected() { commandListener.onPackagerConnected(); } @Override public void onDisconnected() { commandListener.onPackagerDisconnected(); } }; mPackagerClient = new JSPackagerClient( clientId, mSettings.getPackagerConnectionSettings(), handlers, onPackagerConnectedCallback); mPackagerClient.init(); return null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } Android客户端实现一个WebSocket Server大部分使用WebSocket的开发工具,服务端都是pc,Android端都是一个client。经过okhttp的封装,实现client非常简单。 github上找到了两个java websocket server的库,Java-WebSocket和AndroidAsync。尝试写了一下Demo,最终只跑通了AndroidAsync,github:github.com/PortgasAce/… Server的主要代码: AsyncHttpClient.getDefaultInstance().websocket(get, "my-protocol", new WebSocketConnectCallback() { @Override public void onCompleted(Exception ex, WebSocket webSocket) { if (ex != null) { ex.printStackTrace(); return; } webSocket.send("a string"); // webSocket.send(new byte[10]); webSocket.setStringCallback(new StringCallback() { public void onStringAvailable(String s) { System.out.println("I got a string: " + s); } }); webSocket.setDataCallback(new DataCallback() { public void onDataAvailable(DataEmitter emitter, ByteBufferList byteBufferList) { System.out.println("I got some bytes!"); // note that this data has been read byteBufferList.recycle(); } }); } });上面是github的readme,注释了一行webSocket.send(new byte[10]);,否则websocket连接会断掉。 参考知乎WebSocket原理:www.zhihu.com/question/20… 阮一峰WebSocket教程:www.ruanyifeng.com/blog/2017/0… Java-WebSocket:github.com/TooTallNate… AndroidAsync:github.com/koush/Andro… |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |