话不多说先上图:
1、聊天室群聊页面
在线用户的联系人列表
socket连接页面
私聊页面
项目介绍
与服务端实现socket连接:每个客户端连接到服务器的时候,服务器会将每个连接的socket保存在list集合中。
群聊功能:当有一个用户发送群聊消息给服务器的时候,服务器会将所有信息转发给list列表中的所有已连接的客户端。
私聊功能:用户发送私聊信息给服务器后,服务器会向一个目标ip发送消息。
显示在线联系人列表:当有新用户登录成功的时候,服务器会将在线联系人的信息用json字符串的形式发送给客户端,客户端通过解析json字符串来获取在线联系人的信息。
自定义一个强大的类socketevent:客户端与服务器通信全部都是通过这个类来保存数据的,然后使用fastjson工具来把类对象转换为json字符串来传输。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
public class socketevent {
private int type = 0 ;
private string msg = "" ;
private string keyip = "" ; // 关键ip
private string temporaryip = "" ; // 临时ip
public socketevent() {
}
public int gettype() {
return type;
}
public void settype( int type) {
this .type = type;
}
public string getmsg() {
return msg;
}
public void setmsg(string msg) {
this .msg = msg;
}
public string getkeyip() {
return keyip;
}
public void setkeyip(string keyip) {
this .keyip = keyip;
}
public string gettemporaryip() {
return temporaryip;
}
public void settemporaryip(string temporaryip) {
this .temporaryip = temporaryip;
}
}
|
type: 标志当前发送的信息是什么类型的信息。服务端和客户端解 析数据就是通过这个它来判断属于哪种类型的消息
1
2
3
4
5
6
7
8
9
10
11
12
|
public static final int chat_private = 111 ; // 私聊的指令
public static final int chat_group = 222 ; // 群聊的指令
public static final int socket_success = 333 ; // socket连接成功的指令
public static final int socket_fail = 444 ; // socket连接失败的指令
public static final int connect_success = 666 ; // socket连接成功的指令
public static final int connect_fail = 777 ; // socket连接失败的指令
public static final int login_arg = 888 ; // socket接收到标志新用户登录的指令
public static final int cancel_arg = 999 ; // socket接收到标志用户注销的指令
public static final int new_client = 3332 ; // 新用户登录的指令
public static final int all_client = 3432 ; // 新用户登录后接收到所有在线用户的指令
public static final int send_private = 5666 ; // 发送私聊消息的指令
public static final int send_iplist = 6666 ; // 发送已登录的用户ip集合的指令
|
keyip:客户端消息发起者的ip地址
temperoryip:临时的ip地址,如果是type是私聊类型的那么这个ip代表的就是目标联系人的ip地址
服务端代码 (serversocket)
1. 接收客户端的连接
1
|
socket socketclient = server.accept();
|
2.开启线程实时接收来自客户端的信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
// 实时获取客户端发送的数据
@override
public void run() {
try {
while ( true ) {
if ((acceptline = in.readline()) != null ) {
system.out.println( "<接收到的消息是>" + acceptline);
socketevent event = json.parseobject(acceptline, socketevent. class );
switch (event.gettype()) {
case utilfactory.chat_group:
sendmsgavoid(event.getkeyip(), acceptline);
break ;
case utilfactory.send_private:
event.settype(utilfactory.chat_private);
sendmsgtarget(event.gettemporaryip(), json.tojsonstring(event));
break ;
}
}
}
} catch (exception e) {
e.printstacktrace();
}
}
|
3. 向指定ip发送消息的方法和除了自己ip向其他所有ip发送消息的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
// 向指定的ip地址发送消息
private void sendmsgtarget(string targetip, string msg) {
int num = mlist.size();
for ( int index = 0 ; index < num; index++) {
socket msocket = mlist.get(index);
string ip = msocket.getinetaddress().gethostaddress();
if (ip.equals(targetip)) {
printwriter pout = null ;
try {
pout = new printwriter(
new bufferedwriter( new outputstreamwriter(msocket.getoutputstream(), "utf-8" )), true );
pout.println(msg);
// 退出方法
return ;
} catch (ioexception e) {
e.printstacktrace();
}
}
}
}
// 向除了这个ip以外的所有ip发送
private void sendmsgavoid(string avoidip, string msstring) {
int num = mlist.size();
for ( int index = 0 ; index < num; index++) {
socket msocket = mlist.get(index);
string ip = msocket.getinetaddress().gethostaddress();
if (!ip.equals(avoidip)) {
printwriter pout = null ;
try {
pout = new printwriter(
new bufferedwriter( new outputstreamwriter(msocket.getoutputstream(), "utf-8" )), true );
pout.println(msstring);
} catch (ioexception e) {
e.printstacktrace();
}
}
}
}
|
客户端在mainactivity中接受来自服务端的所有信息,根据type来进行再次分装,使用eventbus将信息发送给各个fragment来进行展示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@subscribe (threadmode = threadmode.main)
public void privatechat(socketevent event) {
switch (event.gettype()) {
case myapplication.chat_private:
// 将消息post给私聊聊天室
chatmessagebean bean = new chatmessagebean();
bean.setmsg(event.getmsg());
bean.setname(event.getkeyip());
bean.settype(chatmessagebean.others_arg);
eventbus.getdefault().post(bean);
break ;
case myapplication.send_private:
sendmsg(json.tojsonstring(event));
break ;
}
}
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://blog.csdn.net/jike_chengwei/article/details/71194151