Socket 切换主机地址

1. 创建切换主机接口,ISwitchConnection.java

/**
 * @Description: Socket 切换连接器主机地址
 */
public interface ISwitchConnection {

    /**
     * 关联连接器
     *
     * @param iConnectionManager 连接管理器接口
     */
    void attach(IConnectionManager iConnectionManager);

    /**
     * 切换主机地址
     *
     * @param connectionManager 连接管理器接口
     * @param socketAddress     主机地址
     */
    void switchSocketAddress(IConnectionManager connectionManager, SocketAddress socketAddress);


    /**
     * 分离连接器
     */
    void detach();
}

2. 实现切换主机接口,SwitchConnection.java

/**
 * @Description: Socket 切换连接器的主机地址
 */
public class SwitchConnection extends SocketActionListener implements ISwitchConnection {

    /**
     * 连接管理器
     */
    private IConnectionManager connectionManager;
    /**
     * 主机地址
     */
    private SocketAddress socketAddress;

    /**
     * Socket 连接管理器注册Socket行为是否已销毁
     */
    protected boolean isDetach;

    @Override
    public void attach(IConnectionManager iConnectionManager) {
        if (!isDetach) {
            // 无销毁,开始分离
            detach();
        }
        isDetach = false;
        connectionManager = iConnectionManager;
        //添加监听 Socket 的行为
        connectionManager.subscribeSocketAction(this);
    }

    @Override
    public void detach() {
        isDetach = true;
        if (connectionManager != null) {
            //注销监听 Socket 的行为
            connectionManager.unSubscribeSocketAction(this);
        }
    }

    @Override
    public void switchSocketAddress(IConnectionManager connectionManager, SocketAddress socketAddress) {
        this.socketAddress = socketAddress;
        // 判断的Socket 连接的状态
        if (connectionManager.isConnectViable()) {
            // 设置主机地址
            connectionManager.setSocketAddress(socketAddress);
            // 进行连接
            connectionManager.connect();
        } else {
            // 关联连接器中 Socket 行为监听
            attach(connectionManager);
            // 断开连接
            connectionManager.disConnect(true);
        }
    }

    @Override
    public void onSocketDisconnect(SocketAddress socketAddress, boolean isNeedReconnect) {
        if (connectionManager != null) {
            // 设置主机地址
            connectionManager.setSocketAddress(this.socketAddress);
            // 进行连接
            connectionManager.connect();
        }
        // 解除连接器中的 Socket 行为监听
        detach();
    }
}

3. 在连接管理器类中添加,SuperConnection.java

    /**
     * 切换连接器主机地址
     */
    private ISwitchConnection switchConnection;


    @Override
    public synchronized void connect() {
        LogUtil.i("Socket 开始连接: " + socketAddress.toString());

        if (socketAddress.getIp() == null) {
            throw new NotNullException("请检查是否设置了IP地址.");
        }

        // Socket 状态: 正在连接
        connectionStatus.set(SocketStatus.SOCKET_CONNECTING);

        // 重连管理器
        if (reConnection != null) {
            reConnection.detach(); // 停止分离重连管理器
        }
        reConnection = socketOptions.getReConnectionManager();
        if (reConnection != null) {
            reConnection.attach(this);//关联连接器
        }

        // 开始 Socket 行为分发线程
        if (actionDispatcher != null) {
            actionDispatcher.startDispatchThread();
        }

        // 心跳管理器
        if (heartBeatManager == null) {
            heartBeatManager = new HeartBeatManager(this);
        }

        //  切换连接器主机地址
        if (switchConnection == null) {
            switchConnection = new SwitchConnection();
        }

        // 开启线程,进行连接
        if (connectionExecutor == null || connectionExecutor.isShutdown()) {
            // 核心线程数为 0,非核心线程数可以有 Integer.MAX_VALUE 个,存活时间为 60 秒,适合于在不断的进行连接情况下,避免重复创建和销毁线程
            connectionExecutor = Executors.newCachedThreadPool();
            //LogUtil.i("Executors newCachedThreadPool");
        }
        // 执行连接任务
        connectionExecutor.execute(connectTask);
    }

    @Override
    public void switchSocketAddress(SocketAddress newSocketAddress) {
        // 判断 Socket 是否已连接
        if (connectionStatus.get() == SocketStatus.SOCKET_CONNECTED) {
            // 判断主机地址是否相同
            if (TextUtils.equals(newSocketAddress.getIp(), socketAddress.getIp()) && newSocketAddress.getPort() == socketAddress.getPort()) {
                return;
            }
        }
        // 切换主机地址
        if (switchConnection != null) {
            switchConnection.switchSocketAddress(this, newSocketAddress);
        }
    }

4. 测试布局文件 fragment_switch.xml




    

5. 测试页面,SwitchFragment.java

/**
 * 切换连接器主机地址
 */
public class SwitchFragment extends Fragment {
    IOSocketOptions socketOptions;
    TcpConnection tcpConnection;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_switch, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initSocket();
        initView(view);
    }

    // 初始化 View
    private void initView(View view) {
        view.findViewById(R.id.but_server).setOnClickListener(v ->
                tcpConnection.switchSocketAddress(new SocketAddress("192.168.1.52", 6666)));
        view.findViewById(R.id.but_server2).setOnClickListener(v ->
                tcpConnection.switchSocketAddress(new SocketAddress("192.168.1.52", 9999)));
        view.findViewById(R.id.but_server3).setOnClickListener(v ->
                tcpConnection.switchSocketAddress(new SocketAddress("192.168.1.54", 8888)));
        view.findViewById(R.id.but_server4).setOnClickListener(v ->
                tcpConnection.switchSocketAddress(new SocketAddress("192.168.1.55", 9999)));
        view.findViewById(R.id.but_sender).setOnClickListener(v -> {
            TestSender testMessage = new TestSender();
            testMessage.setMsgId("test_msg");
            testMessage.setFrom("Android");
            tcpConnection.upMessage(testMessage.pack());
        });
    }

    // 初始化 Socket
    private void initSocket() {
        SocketAddress socketAddress = new SocketAddress("192.168.1.52", 6699);
        socketOptions = new IOSocketOptions.Builder()
                .setSocketAddress(socketAddress)
                .setMessageProtocol(new DefaultMessageProtocol())
                .setCallBackIDFactory(new DefaultCallBackIDFactory())
                .build();
        tcpConnection = new TcpConnection(socketAddress);
        tcpConnection.setOptions(socketOptions);
        tcpConnection.connect();
    }
}

6. 测试页图

Socket 切换主机地址_第1张图片

 

你可能感兴趣的:(Android,Socket,Android,Java,TCP)