qq_44173699
CodrStar
2020-11-20 18:15
采纳率: 0%
浏览 329

Android基于socket.io-client-java的聊天客户端连接不上自己实现的服务端

我是想实现一个android的多人聊天室,用了socket-io去实现了客户端和服务端(用socket.io-client-java写的聊天客户端,用于netty-socketio-java实现的服务端),我先用了一个类去访问了我自己写的服务端,是可以来连接上的,还可以进行消息传送!但是!!!我一将客户端的代码放去android端去连接服务端的时候,死活连不上,也没报错,就是没连上服务端,没触发服务端的connect事件,我也加了android的网络权限啊!下面附上我的代码,求大神帮忙解决一下!!!

服务端代码:(在IDEA中实现的)

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.ConnectListener;
import com.corundumstudio.socketio.listener.DataListener;
import com.corundumstudio.socketio.listener.DisconnectListener;
import io.socket.client.Socket;

import java.util.ArrayList;
import java.util.List;

/**
 * @author pengqian
 * @date 2020/11/19 - 14:02
 */
public class ServerSocketIOForAndroid {
    public static void main(String[] args) {
        /**
         * 创建Socket,并设置监听端口
         */
        Configuration config = new Configuration();
        config.setHostname("localhost");
        //设置监听端口
        config.setPort(2000);
        final SocketIOServer server = new SocketIOServer(config);
        System.out.println("服务器创建成功");
        /**
         * 添加连接监听事件,监听是否与客户端连接到服务器
         */
        server.addConnectListener(new ConnectListener() {
            @Override
            public void onConnect(SocketIOClient client) {
                // 判断是否有客户端连接
                if (client != null) {
                    System.out.println("连接成功。。。");
                    System.out.println("连接的客户端的信息是:IP:"+client.getRemoteAddress()+"  SessionID:"+client.getSessionId());
                } else {
                    System.err.println("并没有人连接上。。。");
                }
            }
        });
        server.addDisconnectListener(new DisconnectListener() {
            @Override
            public void onDisconnect(SocketIOClient client) {
                System.out.println(client.getRemoteAddress()+"客户端已经取消连接了");
                client.sendEvent(Socket.EVENT_MESSAGE,"连接关闭");
            }
        });
        /**
         * 添加监听事件,监听客户端的事件
         * 1.第一个参数eventName需要与客户端的事件要一致
         * 2.第二个参数eventClase是传输的数据类型
         * 3.第三个参数listener是用于接收客户端传的数据,数据类型需要与eventClass一致
         */
        server.addEventListener("login", String.class, new DataListener<String>() {
            @Override
            public void onData(SocketIOClient client, String data,
                               AckRequest ackSender) throws Exception {
                // TODO Auto-generated method stub
                System.err.println("接收到客户端的信息为:" + data);
                //向客户端发送消息
                List<String> list = new ArrayList<String>();
                list.add("haode");
                //第一个参数必须与eventName一致,第二个参数data必须与eventClass一致
                client.sendEvent("login", list.toString());
            }
        });
        server.addEventListener(Socket.EVENT_MESSAGE, String.class, new DataListener<String>() {
            @Override
            public void onData(SocketIOClient socketIOClient, String s, AckRequest ackRequest) throws Exception {
                /*接受客户端send(data) 发来的数据*/

                /*
                * sendEvent(eventname,data) 向本广播对象中的全体客户端发送广播。
                  sendEvent(eventname,excludeSocketIOClient,data) 排除指定客户端广播。
                * */
              /*  String[] str=s.split("//");
                if(str[0].equals("0")){
                    //当有客户端连接到服务端 发送给客户端 "0//userName//加人聊天室"  "0//userName//离开聊天室"
                    System.out.println("广播的消息为:"+s);
                    server.getBroadcastOperations().sendEvent(Socket.EVENT_MESSAGE,s);
                }
                if(str[0].equals("1")){
                    str[0]="2";
                    String content=String.join("//",str);
                    System.out.println("消息为:"+content);
                    //客户端发来的数据类型 "1//username//聊天内容"  发送给客户端的消息类型 "2//username//聊天内容"
                    server.getBroadcastOperations().sendEvent(Socket.EVENT_MESSAGE,content);
                }*/
                server.getBroadcastOperations().sendEvent(Socket.EVENT_MESSAGE,s);
            }
        });
        //启动服务
        server.start();
        System.out.println("服务器已启动");
    }
}

可以连接上服务端的客户端代码:这里有个小问题就是如果是从控制台打印的中文字符串发送给服务器,服务器返回的就还是原来的字符串。但是,如果自己自定义一个String类型的中文字符串传给服务器,服务器传回来的中文字符串就变成了?问号,求大神解答!!!

public class Client {

   private static Socket socket;
    public static void main(String[] args) throws IOException {
        try{
            //IO.socket("http://localhost:2000/");可行
            //          "http://127.0.0.1:2000/" 可行
            //                  192.168.74.1
            //                  192.168.56.1
            //                  192.168.196.46
            //                  192.168.196.40
         socket = IO.socket("http://localhost:2000/");
        }catch (URISyntaxException e){
            e.printStackTrace();
        }
        socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {
                System.out.println("此客户端已经连接上服务端了");
                //向服务器发送数据 "0//userName//加人聊天室"
                String joinBrocast="0//"+"x"+"//加入聊天室";
                Boolean b=socket.connected();

                try {
                    socket.send(joinBrocast);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        socket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {
                System.out.println("连接关闭");
                socket.send("0//"+"xxx"+"//离开聊天室");
            }
        });
        socket.on(Socket.EVENT_MESSAGE, new Emitter.Listener() {
            @Override
            public void call(Object... objects) {
                  for(Object obj:objects){
                      System.out.println(obj);
                  }
            }
        });
        //socket.connect();
       socket.connect();
       Boolean a=socket.connected();
        //systemIn();

    }
    private static void systemIn() throws IOException {
       while(true){
            InputStream in = System.in;
            BufferedReader input = new BufferedReader(new InputStreamReader(in));;
            String content = input.readLine();
            socket.send(content);
        }


    }

    }

android客户端的代码(连接不上服务端):(在AS中实现)

/**
 * @author pengqian
 * @date 2020/11/19 - 22:26
 * 连接并获取Socket对象: mSocket = SingleSocket.getInstance().disConnect();
 * 断开连接:SingleSocket.getInstance().disConnect();
 */
public class SingleSocket {
    private Socket mSocket;
    //IO.socket("http://localhost:2000/");
    //          "http://127.0.0.1:2000/"
    //                  192.168.74.1
    //                  192.168.56.1
    //                  192.168.196.46
    //                  192.168.196.40
    public static final String IO_SOCKET_URL="http://localhost:2000/";
    private SingleSocket(){}
    private static class Holder{
        static SingleSocket SIGNAL = new SingleSocket();
    }
    public static SingleSocket getInstance(){
        return Holder.SIGNAL;
    }
    public Socket getSocket() {
        if (mSocket == null) {
            try {
                mSocket = IO.socket(IO_SOCKET_URL);
                mSocket.connect();
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        }
        return mSocket;
    }
    public void disConnect(){
        if(mSocket!=null){
            mSocket.disconnect();
        }
    }
}
public class MainActivity2 extends AppCompatActivity implements View.OnClickListener{
    private TextView textView;
    private EditText editText;
    private Button btn_connect;
    private Button btn_send;
    private Button btn_disConnect;
    private Socket mSocket;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        mSocket = SingleSocket.getInstance().getSocket();
        /*new Thread(new Runnable(){
            @Override
            public void run() {
                mSocket = SingleSocket.getInstance().getSocket();
            }
        }).start();*/
        init();
        btn_connect.setOnClickListener(this);
        btn_send.setOnClickListener(this);
        btn_disConnect.setOnClickListener(this);
        mSocket.on(Socket.EVENT_MESSAGE, new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                textView.setText(args[0].toString());
                System.out.println(mSocket.connected());
            }
        });
        mSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                textView.setText("连接成功!!!");
            }
        });
    }
    private void init(){

        textView=(TextView)findViewById(R.id.testView);
        editText=(EditText)findViewById(R.id.testEdit);
        btn_connect=(Button)findViewById(R.id.btn_connect);
        btn_send=(Button)findViewById(R.id.btn_send);
        btn_disConnect=(Button)findViewById(R.id.btn_disconnect);

    }
    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_connect:{
                if(mSocket.connected()){
                    textView.setText("连接成功");
                }else{
                    textView.setText("连接失败");
                }
                break;
            }
            case R.id.btn_send: {
                mSocket.send(editText.getText().toString().trim());
                editText.setText("");
                break;
            }
            case R.id.btn_disconnect:{
                mSocket.disconnect();
                break;
            }
        }
    }
}

android客户端的依赖包和权限都如下:

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    // https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
    compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.8.1'
    // https://mvnrepository.com/artifact/com.squareup.okio/okio
    compile group: 'com.squareup.okio', name: 'okio', version: '1.13.0'
    // https://mvnrepository.com/artifact/io.socket/engine.io-client
    compile group: 'io.socket', name: 'engine.io-client', version: '1.0.0'
    // https://mvnrepository.com/artifact/io.socket/socket.io-client
    compile group: 'io.socket', name: 'socket.io-client', version: '1.0.0'
    // https://mvnrepository.com/artifact/org.json/json
    //compile group: 'org.json', name: 'json', version: '20090211'
}


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

这个困扰我很久了,我也找过很多帖子,感觉都没有很大的帮助。求大神解决!!! 谢谢了!也欢迎评论区一起讨论。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • Vigiles
    vigiles 2020-11-21 18:20

    中文字符串就变成了?问号是没有进行编码转换,一般发送和接收都用utf-8进行编解码。

    手机访问不到大概是因为这个 public static final String IO_SOCKET_URL="http://localhost:2000/";,
    localhost要换成服务端的IP,比如电脑(服务端)和手机连接的是同一个路由器,那么电脑的ip为192.168.1.102,手机的ip为192.168.1.203,在电脑上直接访问服务端可以用localhost,但手机访问就要用电脑的ip 192.168.1.102 。

    点赞 2 评论
  • q1121323123
    一只菜鸟飞呀飞 2020-12-20 22:00

    你解决了吗,我也遇到一样的问题了,私聊下呗

    点赞 评论
  • qq_44173699
    CodrStar 2020-11-21 20:31

    改成这个地址还是没连接上 我是在Android studio上运行的安卓虚拟机  不是也在电脑端运行吗

    点赞 评论

相关推荐