一個Android輕量級Socket通信框架,既OkHttp後又一力做.
框架開源地址及Demo演示: https://github.com/xuuhaoo/OkSocket
歡迎star,fork,Issue交流
---java
allprojects { repositories { jcenter() } }
dependencies { //基礎的 OkSocket 功能集成包.您的Socket開發不管是客戶端仍是Java,都須要此包 (必須集成) api 'com.tonystark.android:socket:4.1.0' //若是您須要使用 OkSocketServer 功能在客戶端或者Java程序,您還須要依賴下面的Server插件包和上面的一塊兒依賴. api 'com.tonystark.android:socket-server:4.1.0' }
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-dontwarn com.xuhao.didi.socket.client.** -dontwarn com.xuhao.didi.socket.common.** -dontwarn com.xuhao.didi.socket.server.** -dontwarn com.xuhao.didi.core.** -keep class com.xuhao.didi.socket.client.** { *; } -keep class com.xuhao.didi.socket.common.** { *; } -keep class com.xuhao.didi.socket.server.** { *; } -keep class com.xuhao.didi.core.** { *; } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keep class com.xuhao.didi.socket.client.sdk.client.OkSocketOptions$* { *; } -keep class com.xuhao.didi.socket.server.impl.OkServerOptions$* { *; }
Connect
按鈕便可,該服務器僅爲熟悉通信方式和解析方式使用.不能做爲商用服務器. 不用時應及時斷開,保證有限的資源最大化利用公網IP:
104.238.184.237
公網Port:8080
android
//鏈接參數設置(IP,端口號),這也是一個鏈接的惟一標識,不一樣鏈接,該參數中的兩個值至少有其一不同 ConnectionInfo info = new ConnectionInfo("104.238.184.237", 8080); //調用OkSocket,開啓此次鏈接的通道,調用通道的鏈接方法進行鏈接. OkSocket.open(info).connect();
//鏈接參數設置(IP,端口號),這也是一個鏈接的惟一標識,不一樣鏈接,該參數中的兩個值至少有其一不同 ConnectionInfo info = new ConnectionInfo("104.238.184.237", 8080); //調用OkSocket,開啓此次鏈接的通道,拿到通道Manager IConnectionManager manager = OkSocket.open(info); //註冊Socket行爲監聽器,SocketActionAdapter是回調的Simple類,其餘回調方法請參閱類文檔 manager.registerReceiver(new SocketActionAdapter(){ @Override public void onSocketConnectionSuccess(ConnectionInfo info, String action) { Toast.makeText(context, "鏈接成功", LENGTH_SHORT).show(); } }); //調用通道進行鏈接 manager.connect();
//鏈接參數設置(IP,端口號),這也是一個鏈接的惟一標識,不一樣鏈接,該參數中的兩個值至少有其一不同 ConnectionInfo info = new ConnectionInfo("104.238.184.237", 8080); //調用OkSocket,開啓此次鏈接的通道,拿到通道Manager IConnectionManager manager = OkSocket.open(info); //得到當前鏈接通道的參配對象 OkSocketOptions options= manager.getOption(); //基於當前參配對象構建一個參配建造者類 OkSocketOptions.Builder builder = new OkSocketOptions.Builder(options); //修改參配設置(其餘參配請參閱類文檔) builder.setSinglePackageBytes(size); //建造一個新的參配對象而且付給通道 manager.option(builder.build()); //調用通道進行鏈接 manager.connect();
//類A: //...定義將要發送的數據結構體... public class TestSendData implements ISendable { private String str = ""; public TestSendData() { JSONObject jsonObject = new JSONObject(); try { jsonObject.put("cmd", 14); jsonObject.put("data", "{x:2,y:1}"); str = jsonObject.toString(); } catch (JSONException e) { e.printStackTrace(); } } @Override public byte[] parse() { //根據服務器的解析規則,構建byte數組 byte[] body = str.getBytes(Charset.defaultCharset()); ByteBuffer bb = ByteBuffer.allocate(4 + body.length); bb.order(ByteOrder.BIG_ENDIAN); bb.putInt(body.length); bb.put(body); return bb.array(); } } //類B: private IConnectionManager mManager; //...省略鏈接及設置回調的代碼... @Override public void onSocketConnectionSuccess(ConnectionInfo info, String action) { //鏈接成功其餘操做... //鏈式編程調用 OkSocket.open(info) .send(new TestSendData()); }
OkSocket客戶端接收服務器數據是要求必定格式的,客戶端的OkSocketOptions提供了接口來修改默認的服務器返回的包頭解析規則.請看下圖爲默認的包頭包體解析規則
git
如上圖包頭中的內容爲4個字節長度的int型,該int值標識了包體數據區的長度,這就是默認的頭解析,若是須要自定義頭請按照以下方法.github
//設置自定義解析頭 OkSocketOptions.Builder okOptionsBuilder = new OkSocketOptions.Builder(mOkOptions); okOptionsBuilder.setReaderProtocol(new IReaderProtocol() { @Override public int getHeaderLength() { / * * 返回不能爲零或負數的報文頭長度(字節數)。 * 您返回的值應符合服務器文檔中的報文頭的固定長度值(字節數),可能須要與後臺同窗商定 * / return / *固定報文頭的長度(字節數)* /; } @Override public int getBodyLength(byte[] header, ByteOrder byteOrder) { / * * 體長也稱爲有效載荷長度, * 該值應從做爲函數輸入參數的header中讀取。 * 從報文頭數據header中解析有效負載長度時,最好注意參數中的byteOrder。 * 咱們強烈建議您使用java.nio.ByteBuffer來作到這一點。 * 你須要返回有效載荷的長度,而且返回的長度中不該該包含報文頭的固定長度 * / return /*有效負載長度(字節數),固定報文頭長度(字節數)除外*/; } }); //將新的修改後的參配設置給鏈接管理器 mManager.option(okOptionsBuilder.build()); //...正確設置解析頭以後... @Override public void onSocketReadResponse(ConnectionInfo info, String action, OriginalData data) { //遵循以上規則,這個回調才能夠正常收到服務器返回的數據,數據在OriginalData中,爲byte[]數組,該數組數據已經處理過字節序問題,直接放入ByteBuffer中便可使用 }
//類A: //...定義心跳管理器須要的心跳數據類型... public class PulseData implements IPulseSendable { private String str = "pulse"; @Override public byte[] parse() { byte[] body = str.getBytes(Charset.defaultCharset()); ByteBuffer bb = ByteBuffer.allocate(4 + body.length); bb.order(ByteOrder.BIG_ENDIAN); bb.putInt(body.length); bb.put(body); return bb.array(); } } //類B: private IConnectionManager mManager; private PulseData mPulseData = new PulseData; //...省略鏈接及設置回調的代碼... @Override public void onSocketConnectionSuccess(ConnectionInfo info, String action) { //鏈接成功其餘操做... //鏈式編程調用,給心跳管理器設置心跳數據,一個鏈接只有一個心跳管理器,所以數據只用設置一次,若是斷開請再次設置. OkSocket.open(info) .getPulseManager() .setPulseSendable(mPulseData)//只須要設置一次,下一次能夠直接調用pulse() .pulse();//開始心跳,開始心跳後,心跳管理器會自動進行心跳觸發 }
//定義成員變量 private IConnectionManager mManager; //當客戶端收到消息後 @Override public void onSocketReadResponse(ConnectionInfo info, String action, OriginalData data) { if(mManager != null && 是心跳返回包){//是不是心跳返回包,須要解析服務器返回的數據纔可知道 //喂狗操做 mManager.getPulseManager().feed(); } }
//定義成員變量 private IConnectionManager mManager; //...在任意地方... mManager = OkSocket.open(info); if(mManager != null){ PulseManager pulseManager = mManager.getPulseManager(); //手動觸發一次心跳(主要用於一些須要手動控制觸發時機的場景) pulseManager.trigger(); }
mIOThreadMode
isConnectionHolden
mWriteOrder
mReadByteOrder
mHeaderProtocol
mSendSinglePackageBytes
mReadSingleTimeBufferBytes
mPulseFrequency
mPulseFeedLoseTimes
mBackgroundLiveMinute
mConnectTimeoutSecond
mMaxReadDataMB
mReconnectionManager
onSocketIOThreadStart
onSocketIOThreadShutdown
onSocketDisconnection
onSocketConnectionSuccess
onSocketConnectionFailed
onSocketReadResponse
onSocketWriteResponse
onPulseSend
Copyright [2017] [徐昊] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.