当前位置: 移动技术网 > IT编程>开发语言>Java > Java Socket聊天室编程(一)之利用socket实现聊天之消息推送

Java Socket聊天室编程(一)之利用socket实现聊天之消息推送

2019年04月24日  | 移动技术网IT编程  | 我要评论

这篇文章主要介绍了java socket聊天室编程(一)之利用socket实现聊天之消息推送的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下

网上已经有很多利用socket实现聊天的例子了,但是我看过很多,多多少有一些问题存在。

这里我将实现一个比较完整的聊天例子,并解释其中的逻辑。

由于socket这一块比较大,所以我将分出几篇来写一个比较完整的socket例子。

这里我们先来实现一个最简单的,服务器与客户端通讯,实现消息推送的功能。

目的:服务器与客户端建立连接,客户端可以向服务器发送消息,服务器可以向客户端推送消息。

1,使用java建立socket聊天服务器

1,socketurls 确定ip地址和端口号

public class socketurls{
// ip地址
public final static string ip = "192.168.1.110";
// 端口号
public final static int port = 8888;
}

2,main 程序的入口

public class main {
public static void main(string[] args) throws exception {
new chatserver().initserver();
}
}

3,bean 实体类

用户信息 userinfobean

public class main {
 
public static void main(string[] args) throws exception {
new chatserver().initserver();
}
}

聊天信息 messagebean

public class messagebean extends userinfobean {
private long messageid;// 消息id
private long groupid;// 群id
private boolean isgoup;// 是否是群消息
private int chattype;// 消息类型;1,文本;2,图片;3,小视频;4,文件;5,地理位置;6,语音;7,视频通话
private string content;// 文本消息内容
private string errormsg;// 错误信息
private int errorcode;// 错误代码
//省略get/set方法
}

4,chatserver 聊天服务,最主要的程序

public class chatserver {
// socket服务
private static serversocket server;
public gson gson = new gson();
/**
* 初始化socket服务
*/
public void initserver() {
try {
// 创建一个serversocket在端口8080监听客户请求
server = new serversocket(socketurls.port);
createmessage();
} catch (ioexception e) {
// todo auto-generated catch block
e.printstacktrace();
}
}
/**
* 创建消息管理,一直接收消息
*/
private void createmessage() {
try {
system.out.println("等待用户接入 : ");
// 使用accept()阻塞等待客户请求
socket socket = server.accept();
system.out.println("用户接入 : " + socket.getport());
// 开启一个子线程来等待另外的socket加入
new thread(new runnable() {
public void run() {
createmessage();
}
}).start();
// 向客户端发送信息
outputstream output = socket.getoutputstream();
// 从客户端获取信息
bufferedreader bff = new bufferedreader(new inputstreamreader(socket.getinputstream()));
// scanner scanner = new scanner(socket.getinputstream());
new thread(new runnable() {
public void run() {
try {
string buffer;
while (true) {
// 从控制台输入
bufferedreader strin = new bufferedreader(new inputstreamreader(system.in));
buffer = strin.readline();
// 因为readline以换行符为结束点所以,结尾加入换行
buffer += "
";
output.write(buffer.getbytes("utf-8"));
// 发送数据
output.flush();
}
} catch (ioexception e) {
// todo auto-generated catch block
e.printstacktrace();
}
}
}).start();
// 读取发来服务器信息
string line = null;
// 循环一直接收当前socket发来的消息
while (true) {
thread.sleep(500);
// system.out.println("内容 : " + bff.readline());
// 获取客户端的信息
while ((line = bff.readline()) != null) {
messagebean messagebean = gson.fromjson(line, messagebean.class);
system.out.println("用户 : " + messagebean.getusername());
system.out.println("内容 : " + messagebean.getcontent());
}
}
// server.close();
} catch (exception e) {
// todo auto-generated catch block
e.printstacktrace();
system.out.println("错误 : " + e.getmessage());
}
}
}

2,android 端作为移动端连接服务器

1,appliaction 实例化一个全局的聊天服务

public class chatappliaction extends application {
public static chatserver chatserver;
public static userinfobean userinfobean;
@override
public void oncreate() {
super.oncreate();
}
}

2,ip地址和端口号和服务器保持一致

3,聊天实力类同服务器端一样

4,xml布局。登陆,聊天

1,登录

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<edittext
android:id="@+id/chat_name_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="用户名"
android:text="admin"/>
<edittext
android:id="@+id/chat_pwd_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"
android:text="123123123a"
android:inputtype="numberpassword" />
<button
android:id="@+id/chat_login_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="登录" />
</linearlayout>

2,聊天

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activity.mainactivity">
<scrollview
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.9">
<linearlayout
android:id="@+id/chat_ly"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</linearlayout>
</scrollview>
<linearlayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<edittext
android:id="@+id/chat_et"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.8" />
<button
android:id="@+id/send_btn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:text="发送" />
</linearlayout>
</linearlayout>

5,loginactivity 登陆

public class loginactivity extends appcompatactivity {
private edittext chat_name_text, chat_pwd_text;
private button chat_login_btn;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_login);
chat_name_text = (edittext) findviewbyid(r.id.chat_name_text);
chat_pwd_text = (edittext) findviewbyid(r.id.chat_pwd_text);
chat_login_btn = (button) findviewbyid(r.id.chat_login_btn);
chat_login_btn.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
if (getlogin(chat_name_text.gettext().tostring().trim(), chat_pwd_text.gettext().tostring().trim())) {
getchatserver();
intent intent = new intent(loginactivity.this, mainactivity.class);
startactivity(intent);
finish();
}
}
});
}
private boolean getlogin(string name, string pwd) {
if (textutils.isempty(name) || textutils.isempty(pwd)) return false;
if (name.equals("admin") && pwd.equals("123123123a")) return true;
return false;
}
private void getchatserver() {
chatappliaction.chatserver = new chatserver();
}
}

6,mainactivity 聊天

public class mainactivity extends appcompatactivity {
private linearlayout chat_ly;
private textview left_text, right_view;
private edittext chat_et;
private button send_btn;
private viewgroup.layoutparams layoutparams = new viewgroup.layoutparams(viewgroup.layoutparams.match_parent, viewgroup.layoutparams.wrap_content);
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
chat_ly = (linearlayout) findviewbyid(r.id.chat_ly);
chat_et = (edittext) findviewbyid(r.id.chat_et);
send_btn = (button) findviewbyid(r.id.send_btn);
send_btn.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
chatappliaction.chatserver.sendmessage(chat_et.gettext().tostring().trim());
chat_ly.addview(initrightview(chat_et.gettext().tostring().trim()));
}
});
//添加消息接收队列
chatappliaction.chatserver.setchathandler(new handler() {
@override
public void handlemessage(message msg) {
if (msg.what == 1) {
//发送回来消息后,更新ui
chat_ly.addview(initleftview(msg.obj.tostring()));
}
}
});
}
/**靠右的消息
* @param messagecontent
* @return
*/
private view initrightview(string messagecontent) {
right_view = new textview(this);
right_view.setlayoutparams(layoutparams);
right_view.setgravity(view.focus_right);
right_view.settext(messagecontent);
return right_view;
}
/**靠左的消息
* @param messagecontent
* @return
*/
private view initleftview(string messagecontent) {
left_text = new textview(this);
left_text.setlayoutparams(layoutparams);
left_text.setgravity(view.focus_left);
left_text.settext(messagecontent);
return left_text;
}
}

7,chatserver 聊天逻辑,最主要的

 

public class chatserver {
private socket socket;
private handler handler;
private messagebean messagebean;
private gson gson = new gson();
// 由socket对象得到输出流,并构造printwriter对象
printwriter printwriter;
inputstream input;
outputstream output;
dataoutputstream dataoutputstream;
public chatserver() {
initmessage();
initchatserver();
}
/**
* 消息队列,用于传递消息
*
* @param handler
*/
public void setchathandler(handler handler) {
this.handler = handler;
}
private void initchatserver() {
//开个线程接收消息
receivemessage();
}
/**
* 初始化用户信息
*/
private void initmessage() {
messagebean = new messagebean();
messagebean.setuserid(1);
messagebean.setmessageid(1);
messagebean.setchattype(1);
messagebean.setusername("admin");
chatappliaction.userinfobean = messagebean;
}
/**
* 发送消息
*
* @param contentmsg
*/
public void sendmessage(string contentmsg) {
try {
if (socket == null) {
message message = handler.obtainmessage();
message.what = 1;
message.obj = "服务器已经关闭";
handler.sendmessage(message);
return;
}
byte[] str = contentmsg.getbytes("utf-8");//将内容转utf-8
string aaa = new string(str);
messagebean.setcontent(aaa);
string messagejson = gson.tojson(messagebean);
/**
* 因为服务器那边的readline()为阻塞读取
* 如果它读取不到换行符或者输出流结束就会一直阻塞在那里
* 所以在json消息最后加上换行符,用于告诉服务器,消息已经发送完毕了
* */
messagejson += "
";
output.write(messagejson.getbytes("utf-8"));// 换行打印
output.flush(); // 刷新输出流,使server马上收到该字符串
} catch (exception e) {
e.printstacktrace();
log.e("test", "错误:" + e.tostring());
}
}
/**
* 接收消息,在子线程中
*/
private void receivemessage() {
new thread(new runnable() {
@override
public void run() {
try {
// 向本机的8080端口发出客户请求
socket = new socket(socketurls.ip, socketurls.port);
// 由socket对象得到输入流,并构造相应的bufferedreader对象
printwriter = new printwriter(socket.getoutputstream());
input = socket.getinputstream();
output = socket.getoutputstream();
dataoutputstream = new dataoutputstream(socket.getoutputstream());
// 从客户端获取信息
bufferedreader bff = new bufferedreader(new inputstreamreader(input));
// 读取发来服务器信息
string line;
while (true) {
thread.sleep(500);
// 获取客户端的信息
while ((line = bff.readline()) != null) {
log.i("socket", "内容 : " + line);
message message = handler.obtainmessage();
message.obj = line;
message.what = 1;
handler.sendmessage(message);
}
if (socket == null)
break;
}
output.close();//关闭socket输出流
input.close();//关闭socket输入流
socket.close();//关闭socket
} catch (exception e) {
e.printstacktrace();
log.e("test", "错误:" + e.tostring());
}
}
}).start();
}
}

写到这里,已经完成了所有的代码。

这个demo可以实现手机端向服务器发送消息,服务器向手机端发送消息。

这个demo可以算是推送功能,不过真正的推送没有这么简单。作为一个socket的入门了解,可以从中看到socket编程的思想。

以上所述是小编给大家介绍的java socket聊天室编程(一)之利用socket实现聊天之消息推送,希望对大家有所帮助,如果大家有任何疑问请给我留言。


 

     微信扫码,欢迎关注微信公众账号,更多精彩~

          手机扫码加入qq群,欢迎你~

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网