我是想实现一个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" />
这个困扰我很久了,我也找过很多帖子,感觉都没有很大的帮助。求大神解决!!! 谢谢了!也欢迎评论区一起讨论。