小弟菜鸟一名,因为好奇,所以想研究websocket的连接,因为重来没做过,所以一路坎坷,问了不少大神,结果因为基础太差被屌的体无完肤,不过最终还是完成了!一切都是值得的。
接下来就开始讲讲如何使用okhttp3来连接websocket吧。
首先依赖
compile 'com.squareup.okhttp3:okhttp:3.8.1'
okhttp3在3.5以上就开始支持websocket连接了,所以版本一定要在3.5以上。
然后去加网络权限
android:name="android.permission.INTERNET" />
为了切换activity的后,也可以继续接受和发送信息,所以我写了一个service
public class Servicetcp extends Service{ @Nullable @Override public IBinder onBind(Intent intent) { return null; } Request request; @Override public void onCreate() { super.onCreate(); request = new Request.Builder() .url("ws://echo.websocket.org") .build(); OkHttpClient client = new OkHttpClient(); client.newWebSocket(request, Urlservice.getinstace()); client.dispatcher().executorService().shutdown(); } }这样在不断切换activity的时候就不会有影响了。(虽然不知道对不对,但我是这样想的)
接下来我们重写WebSocketListener这个类;
private Handler mDelivery; WebListener http; WebSocket webSocket; public void setHttp(WebListener listener) { this.http = listener; } private Urlservice() { } private static Urlservice urlservice; public static Urlservice getinstace() { if (urlservice == null) { synchronized (Urlservice.class) { if (urlservice == null) { urlservice = new Urlservice(); } } } return urlservice; } public void clearListener() { this.http = null; } @Override public void onOpen(WebSocket webSocket, Response response) { this.webSocket = webSocket; mDelivery = new Handler(Looper.getMainLooper()); webSocket.send("hello world"); webSocket.send("welcome"); // webSocket.send(ByteString.decodeHex("adef")); // webSocket.close(1000, "再见"); } @Override public void onMessage(WebSocket webSocket, final String text) { System.out.println("onMessage: " + text); mDelivery.post(new Runnable() { @Override public void run() { if (http != null) { http.output("onMessage: " + text); } } }); } @Override public void onMessage(WebSocket webSocket, ByteString bytes) { System.out.println("onMessage byteString: " + bytes); // http.output("onMessage byteString: " + bytes); } @Override public void onClosing(WebSocket webSocket, int code, String reason) { webSocket.close(1000, null); System.out.println("onClosing: " + code + "/" + reason); // http.output("onClosing: " + code + "/" + reason); } @Override public void onClosed(WebSocket webSocket, int code, String reason) { // http.output("onClosed: " + code + "/" + reason); System.out.println("onClosed: " + code + "/" + reason); } @Override public void onFailure(WebSocket webSocket, Throwable t, Response response) { // output("onFailure: " + t.getMessage()); } /** * @param s * @return */ public boolean sendMessage(String s) { return webSocket.send(s); } public boolean closeMessage(){ return webSocket.close(1000,""); }接收消息的是onMessage方法,是服务器返回的信息。
我写了一个接口,把消息给传出去了,记住要用handler,不然会出问题的,在异步线程里运行就没问题,千万不要去主线程里运行,会阻塞的。
还写了一个单例,用来实例化(PS:因为我基础太差,对单例了解不多,基本上属于不会,所以这里被喷惨了)
接下来是接口(写就写一套,以免有和我一样的小白,差一点就看不懂)
public interface WebListener { public void output(final String content); }基本设施算是完成啦,记得去manifest里把service配置好。
android:name=".Servicetcp" />
接下来是activity里的操作了,以及传值和接收值
public class MainActivity extends AppCompatActivity implements WebListener { private Button start, fasong; private TextView text; Intent it; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); start = (Button) findViewById(R.id.start); text = (TextView) findViewById(R.id.text); fasong = findViewById(R.id.fasong); it = new Intent(MainActivity.this, Servicetcp.class); startService(it); fasong.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Urlservice.getinstace().sendMessage("acccasdsadsadsasa"); } }); start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent it = new Intent(MainActivity.this, Main2Activity.class); startActivity(it); } }); } @Override protected void onResume() { super.onResume(); Urlservice.getinstace().setHttp(this); } @Override public void output(final String message) { text.setText(text.getText().toString() + message + "\n"); } @Override protected void onStop() { super.onStop(); } @Override protected void onDestroy() { super.onDestroy(); } }activity是要实现接口的,不然没办法取到服务器返回的值的;
在oncreate()方法里先启动service
接下来就是运行单例,这样接口就算是实例化了。
Urlservice.getinstace().setHttp(this);不过为了方便,我建议把单例的实例化写在onResume()方法里,这样从别的页面finish回来的时候,就直接抢夺了接口,可以直接使用,其他界面也一样。
实现接口后会弹出output方法
@Override public void output(final String message) { text.setText(text.getText().toString() + message + "\n"); }在这里就可以对服务器回传的值进行操作了。
基本上就这么多了,我语言表达能力也不好。技术又菜,各位大佬有发现错误的地方,请告诉我,我好进行修改。