Android之okhttp实现socket通讯(非原创)

文章大纲

一、okhttp基础介绍
二、socket通讯代码实战
三、项目源码下载
四、参考文章

 

一、okhttp基础介绍

https://www.jianshu.com/p/e3291b7808e7

二、socket通讯代码实战

1. 添加依赖和权限

app的build.gradle下添加okhttp依赖

implementation 'com.squareup.okhttp3:okhttp:3.8.1'
 

AndroidManifest.xml文件添加网络权限

<uses-permission  android:name="android.permission.INTERNET" />
 

2. 添加布局文件

activity_main.xml文件中代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/start2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start2"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

3. MainActivity逻辑实现

package aidl_customer.com.wj.http_socket;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

/**
 * okhttp是3.5以后才添加对WebSocket的支持
 */
public class MainActivity extends AppCompatActivity {

    private Button start;
    private TextView text;

    private Button start2;
    private TextView text2;

    @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);

        start2 = (Button) findViewById(R.id.start2);
        text2 = (TextView) findViewById(R.id.text2);

        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                connect();
            }
        });

        start2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                OkHttpClient  client = new OkHttpClient.Builder()
                        .readTimeout(3, TimeUnit.SECONDS)
                        .build();


                Request request = new Request.Builder()
                        .url("ws://echo.websocket.org")
                        .build();
                WebSocket webSocket = client.newWebSocket(request, new WebSocketListener() {
                    @Override
                    public void onOpen(WebSocket webSocket, Response response) {
                        super.onOpen(webSocket, response);
                    }

                    @Override
                    public void onMessage(WebSocket webSocket, String text) {
                        super.onMessage(webSocket, text);
                    }

                    @Override
                    public void onMessage(WebSocket webSocket, ByteString bytes) {
                        super.onMessage(webSocket, bytes);
                    }

                    @Override
                    public void onClosing(WebSocket webSocket, int code, String reason) {
                        super.onClosing(webSocket, code, reason);
                    }

                    @Override
                    public void onClosed(WebSocket webSocket, int code, String reason) {
                        super.onClosed(webSocket, code, reason);
                    }

                    @Override
                    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                        super.onFailure(webSocket, t, response);
                    }
                });
            }
        });
    }

    /**
     *WebSocket官网就提供了相应url可以测试
     */
    private void connect() {

        //建立连接
        EchoWebSocketListener listener = new EchoWebSocketListener();
        Request request = new Request.Builder()
                .url("ws://echo.websocket.org")
                .build();
        OkHttpClient client = new OkHttpClient();
        client.newWebSocket(request, listener);

        client.dispatcher().executorService().shutdown();
    }

    /**
     * 重写了WebSocketListener中的几个方法,这几个方法很好理解,是用来异步回调的,
     * 这里简单说一下:onOpen当WebSocket和远程建立连接时回调;两个onMessage就是接收到消息时回调,
     * 只是消息内容的类型不同;onClosing是当远程端暗示没有数据交互时回调(即此时准备关闭,但连接还没有关闭);
     * onClosed就是当连接已经释放的时候被回调;onFailure当然是失败时被回调(包括连接失败,发送失败等)。
     *
     * send用来发送消息;close用来关闭连接
     */
    private final class EchoWebSocketListener extends WebSocketListener {

        @Override
        public void onOpen(WebSocket webSocket, Response response) {

            webSocket.send("hello world");
            webSocket.send("welcome");
            webSocket.send(ByteString.decodeHex("adef"));
            webSocket.close(1000, "再见");
        }

        @Override
        public void onMessage(WebSocket webSocket, String text) {
            output("onMessage: " + text);
        }

        @Override
        public void onMessage(WebSocket webSocket, ByteString bytes) {
            output("onMessage byteString: " + bytes);
        }

        @Override
        public void onClosing(WebSocket webSocket, int code, String reason) {
            webSocket.close(1000, null);
            output("onClosing: " + code + "/" + reason);
        }

        @Override
        public void onClosed(WebSocket webSocket, int code, String reason) {
            output("onClosed: " + code + "/" + reason);
        }

        @Override
        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
            output("onFailure: " + t.getMessage());
        }
    }

    private void output(final String content) {

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                text.setText(text.getText().toString() + content + "\n");
            }
        });
    }
}

温馨提示:
(1)EchoWebSocketListener继承OkHttp中的抽象类WebSocketListener,重写了几个方法,是用来异步回调的,这里简单说一下:onOpen当WebSocket和远程建立连接时回调;两个onMessage就是接收到消息时回调,只是消息内容的类型不同;onClosing是当远程端暗示没有数据交互时回调(即此时准备关闭,但连接还没有关闭);onClosed就是当连接已经释放的时候被回调;onFailure当然是失败时被回调(包括连接失败,发送失败等)。
(2)send用来发送消息;close用来关闭连接
(3)WebSocket官网就提供了相应url可以测试,测试地址为:ws://echo.websocket.org
(4)关闭连接方式,OkHttp提供两个方法来关闭连接:
  1)close webSocket.close(0, “bye”);请求服务器优雅地关闭连接然后等待确认。在关闭之前,所有已经在队列中的消息将被传送完毕。 既然涉及到交互,那么socket可能不会立即关闭。如果初始化和关闭连接是和Activity的生命周期绑定的(比如onPause/onResume),有一些消息可能是在close被调用之后接收到,所以这需要小心去处理。
  2)cancel;cancel更加残忍:它会丢弃所有已经在队列中的消息然后残忍地关闭socket。这样也有优点:不必等待家政(housekeeping)和已在队列中消息的传送。然而,选择cancel还是close取决于使用场景。

4. 项目运行与访问

安装apk后,运行主页面如下:

 

点击START按钮,出现以下结果

 

三、项目源码下载

链接:https://pan.baidu.com/s/1t8OmZy8WLZr2aKI8S2XcwQ
提取码:jwzi

四、参考文章

    1. https://blog.csdn.net/xlh1191860939/article/details/75452342/
    2. https://blog.csdn.net/xlh1191860939/article/details/75452513
posted @ 2019-06-11 16:00 故事爱人 阅读(...) 评论(...) 编辑 收藏