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

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

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

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

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

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

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

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

  1. public class SocketUrls{
  2. // ip地址
  3. public final static String IP = "192.168.1.110";
  4. // 端口号
  5. ;
  6. }

2,Main 程序的入口

  1. public class Main {
  2. public static void main(String[] args) throws Exception {
  3. new ChatServer().initServer();
  4. }
  5. }

3,Bean 实体类

用户信息 UserInfoBean

  1. public class Main {
  2.  
  3. public static void main(String[] args) throws Exception {
  4. new ChatServer().initServer();
  5. }
  6. }

聊天信息 MessageBean

  1. public class MessageBean extends UserInfoBean {
  2. private long messageId;// 消息id
  3. private long groupId;// 群id
  4. private boolean isGoup;// 是否是群消息
  5. private int chatType;// 消息类型;1,文本;2,图片;3,小视频;4,文件;5,地理位置;6,语音;7,视频通话
  6. private String content;// 文本消息内容
  7. private String errorMsg;// 错误信息
  8. private int errorCode;// 错误代码
  9. //省略get/set方法
  10. }

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

  1. public class ChatServer {
  2. // socket服务
  3. private static ServerSocket server;
  4. public Gson gson = new Gson();
  5. /**
  6. * 初始化socket服务
  7. */
  8. public void initServer() {
  9. try {
  10. // 创建一个ServerSocket在端口8080监听客户请求
  11. server = new ServerSocket(SocketUrls.PORT);
  12. createMessage();
  13. } catch (IOException e) {
  14. // TODO Auto-generated catch block
  15. e.printStackTrace();
  16. }
  17. }
  18. /**
  19. * 创建消息管理,一直接收消息
  20. */
  21. private void createMessage() {
  22. try {
  23. System.out.println("等待用户接入 : ");
  24. // 使用accept()阻塞等待客户请求
  25. Socket socket = server.accept();
  26. System.out.println("用户接入 : " + socket.getPort());
  27. // 开启一个子线程来等待另外的socket加入
  28. new Thread(new Runnable() {
  29. public void run() {
  30. createMessage();
  31. }
  32. }).start();
  33. // 向客户端发送信息
  34. OutputStream output = socket.getOutputStream();
  35. // 从客户端获取信息
  36. BufferedReader bff = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  37. // Scanner scanner = new Scanner(socket.getInputStream());
  38. new Thread(new Runnable() {
  39. public void run() {
  40. try {
  41. String buffer;
  42. while (true) {
  43. // 从控制台输入
  44. BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
  45. buffer = strin.readLine();
  46. // 因为readLine以换行符为结束点所以,结尾加入换行
  47. buffer += "
  48. ";
  49. output.write(buffer.getBytes("utf-8"));
  50. // 发送数据
  51. output.flush();
  52. }
  53. } catch (IOException e) {
  54. // TODO Auto-generated catch block
  55. e.printStackTrace();
  56. }
  57. }
  58. }).start();
  59. // 读取发来服务器信息
  60. String line = null;
  61. // 循环一直接收当前socket发来的消息
  62. while (true) {
  63. Thread.sleep();
  64. // System.out.println("内容 : " + bff.readLine());
  65. // 获取客户端的信息
  66. while ((line = bff.readLine()) != null) {
  67. MessageBean messageBean = gson.fromJson(line, MessageBean.class);
  68. System.out.println("用户 : " + messageBean.getUserName());
  69. System.out.println("内容 : " + messageBean.getContent());
  70. }
  71. }
  72. // server.close();
  73. } catch (Exception e) {
  74. // TODO Auto-generated catch block
  75. e.printStackTrace();
  76. System.out.println("错误 : " + e.getMessage());
  77. }
  78. }
  79. }

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

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

  1. public class ChatAppliaction extends Application {
  2. public static ChatServer chatServer;
  3. public static UserInfoBean userInfoBean;
  4. @Override
  5. public void onCreate() {
  6. super.onCreate();
  7. }
  8. }

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

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

4,xml布局。登陆,聊天

1,登录

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical">
  6. <EditText
  7. android:id="@+id/chat_name_text"
  8. android:layout_width="match_parent"
  9. android:layout_height="wrap_content"
  10. android:hint="用户名"
  11. android:text="admin"/>
  12. <EditText
  13. android:id="@+id/chat_pwd_text"
  14. android:layout_width="match_parent"
  15. android:layout_height="wrap_content"
  16. android:hint="密码"
  17. android:text="123123123a"
  18. android:inputType="numberPassword" />
  19. <Button
  20. android:id="@+id/chat_login_btn"
  21. android:layout_width="match_parent"
  22. android:layout_height="wrap_content"
  23. android:hint="登录" />
  24. </LinearLayout>

2,聊天

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical"
  7. tools:context=".activity.MainActivity">
  8. <ScrollView
  9. android:id="@+id/scrollView"
  10. android:layout_width="match_parent"
  11. android:layout_height="0dp"
  12. android:layout_weight="0.9">
  13. <LinearLayout
  14. android:id="@+id/chat_ly"
  15. android:layout_width="match_parent"
  16. android:layout_height="match_parent"
  17. android:orientation="vertical">
  18. </LinearLayout>
  19. </ScrollView>
  20. <LinearLayout
  21. android:layout_width="match_parent"
  22. android:layout_height="wrap_content"
  23. android:orientation="horizontal">
  24. <EditText
  25. android:id="@+id/chat_et"
  26. android:layout_width="0dp"
  27. android:layout_height="match_parent"
  28. android:layout_weight="0.8" />
  29. <Button
  30. android:id="@+id/send_btn"
  31. android:layout_width="0dp"
  32. android:layout_height="match_parent"
  33. android:layout_weight="0.2"
  34. android:text="发送" />
  35. </LinearLayout>
  36. </LinearLayout>

5,LoginActivity 登陆

  1. public class LoginActivity extends AppCompatActivity {
  2. private EditText chat_name_text, chat_pwd_text;
  3. private Button chat_login_btn;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_login);
  8. chat_name_text = (EditText) findViewById(R.id.chat_name_text);
  9. chat_pwd_text = (EditText) findViewById(R.id.chat_pwd_text);
  10. chat_login_btn = (Button) findViewById(R.id.chat_login_btn);
  11. chat_login_btn.setOnClickListener(new View.OnClickListener() {
  12. @Override
  13. public void onClick(View v) {
  14. if (getLogin(chat_name_text.getText().toString().trim(), chat_pwd_text.getText().toString().trim())) {
  15. getChatServer();
  16. Intent intent = new Intent(LoginActivity.this, MainActivity.class);
  17. startActivity(intent);
  18. finish();
  19. }
  20. }
  21. });
  22. }
  23. private boolean getLogin(String name, String pwd) {
  24. if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd)) return false;
  25. if (name.equals("admin") && pwd.equals("123123123a")) return true;
  26. return false;
  27. }
  28. private void getChatServer() {
  29. ChatAppliaction.chatServer = new ChatServer();
  30. }
  31. }

6,MainActivity 聊天

  1. public class MainActivity extends AppCompatActivity {
  2. private LinearLayout chat_ly;
  3. private TextView left_text, right_view;
  4. private EditText chat_et;
  5. private Button send_btn;
  6. private ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. chat_ly = (LinearLayout) findViewById(R.id.chat_ly);
  12. chat_et = (EditText) findViewById(R.id.chat_et);
  13. send_btn = (Button) findViewById(R.id.send_btn);
  14. send_btn.setOnClickListener(new View.OnClickListener() {
  15. @Override
  16. public void onClick(View v) {
  17. ChatAppliaction.chatServer.sendMessage(chat_et.getText().toString().trim());
  18. chat_ly.addView(initRightView(chat_et.getText().toString().trim()));
  19. }
  20. });
  21. //添加消息接收队列
  22. ChatAppliaction.chatServer.setChatHandler(new Handler() {
  23. @Override
  24. public void handleMessage(Message msg) {
  25. ) {
  26. //发送回来消息后,更新ui
  27. chat_ly.addView(initLeftView(msg.obj.toString()));
  28. }
  29. }
  30. });
  31. }
  32. /**靠右的消息
  33. * @param messageContent
  34. * @return
  35. */
  36. private View initRightView(String messageContent) {
  37. right_view = new TextView(this);
  38. right_view.setLayoutParams(layoutParams);
  39. right_view.setGravity(View.FOCUS_RIGHT);
  40. right_view.setText(messageContent);
  41. return right_view;
  42. }
  43. /**靠左的消息
  44. * @param messageContent
  45. * @return
  46. */
  47. private View initLeftView(String messageContent) {
  48. left_text = new TextView(this);
  49. left_text.setLayoutParams(layoutParams);
  50. left_text.setGravity(View.FOCUS_LEFT);
  51. left_text.setText(messageContent);
  52. return left_text;
  53. }
  54. }

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

  1. public class ChatServer {
  2. private Socket socket;
  3. private Handler handler;
  4. private MessageBean messageBean;
  5. private Gson gson = new Gson();
  6. // 由Socket对象得到输出流,并构造PrintWriter对象
  7. PrintWriter printWriter;
  8. InputStream input;
  9. OutputStream output;
  10. DataOutputStream dataOutputStream;
  11. public ChatServer() {
  12. initMessage();
  13. initChatServer();
  14. }
  15. /**
  16. * 消息队列,用于传递消息
  17. *
  18. * @param handler
  19. */
  20. public void setChatHandler(Handler handler) {
  21. this.handler = handler;
  22. }
  23. private void initChatServer() {
  24. //开个线程接收消息
  25. receiveMessage();
  26. }
  27. /**
  28. * 初始化用户信息
  29. */
  30. private void initMessage() {
  31. messageBean = new MessageBean();
  32. messageBean.setUserId(1);
  33. messageBean.setMessageId(1);
  34. messageBean.setChatType(1);
  35. messageBean.setUserName("admin");
  36. ChatAppliaction.userInfoBean = messageBean;
  37. }
  38. /**
  39. * 发送消息
  40. *
  41. * @param contentMsg
  42. */
  43. public void sendMessage(String contentMsg) {
  44. try {
  45. if (socket == null) {
  46. Message message = handler.obtainMessage();
  47. message.what = 1;
  48. message.obj = "服务器已经关闭";
  49. handler.sendMessage(message);
  50. return;
  51. }
  52. byte[] str = contentMsg.getBytes("utf-8");//将内容转utf-8
  53. String aaa = new String(str);
  54. messageBean.setContent(aaa);
  55. String messageJson = gson.toJson(messageBean);
  56. /**
  57. * 因为服务器那边的readLine()为阻塞读取
  58. * 如果它读取不到换行符或者输出流结束就会一直阻塞在那里
  59. * 所以在json消息最后加上换行符,用于告诉服务器,消息已经发送完毕了
  60. * */
  61. messageJson += "
  62. ";
  63. output.write(messageJson.getBytes("utf-8"));// 换行打印
  64. output.flush(); // 刷新输出流,使Server马上收到该字符串
  65. } catch (Exception e) {
  66. e.printStackTrace();
  67. Log.e("test", "错误:" + e.toString());
  68. }
  69. }
  70. /**
  71. * 接收消息,在子线程中
  72. */
  73. private void receiveMessage() {
  74. new Thread(new Runnable() {
  75. @Override
  76. public void run() {
  77. try {
  78. // 向本机的8080端口发出客户请求
  79. socket = new Socket(SocketUrls.IP, SocketUrls.PORT);
  80. // 由Socket对象得到输入流,并构造相应的BufferedReader对象
  81. printWriter = new PrintWriter(socket.getOutputStream());
  82. input = socket.getInputStream();
  83. output = socket.getOutputStream();
  84. dataOutputStream = new DataOutputStream(socket.getOutputStream());
  85. // 从客户端获取信息
  86. BufferedReader bff = new BufferedReader(new InputStreamReader(input));
  87. // 读取发来服务器信息
  88. String line;
  89. while (true) {
  90. Thread.sleep(500);
  91. // 获取客户端的信息
  92. while ((line = bff.readLine()) != null) {
  93. Log.i("socket", "内容 : " + line);
  94. Message message = handler.obtainMessage();
  95. message.obj = line;
  96. message.what = 1;
  97. handler.sendMessage(message);
  98. }
  99. if (socket == null)
  100. break;
  101. }
  102. output.close();//关闭Socket输出流
  103. input.close();//关闭Socket输入流
  104. socket.close();//关闭Socket
  105. } catch (Exception e) {
  106. e.printStackTrace();
  107. Log.e("test", "错误:" + e.toString());
  108. }
  109. }
  110. }).start();
  111. }
  112. }

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

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

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

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


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

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

Java Socket聊天室编程(一)之利用socket实现聊天之消息推送的更多相关文章

  1. Java Socket聊天室编程(二)之利用socket实现单聊聊天室

    这篇文章主要介绍了Java Socket聊天室编程(二)之利用socket实现单聊聊天室的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下 在上篇文章Java Socket聊天室编程(一)之 ...

  2. 结合实际需求,在webapi内利用WebSocket建立单向的消息推送平台,让A页面和服务端建立WebSocket连接,让其他页面可以及时给A页面推送消息

    1.需求示意图 2.需求描述 原本是为了给做unity3d客户端开发的同事提供不定时的消息推送,比如商城购买道具后服务端将道具信息推送给客户端. 本篇文章简化理解,用“相关部门开展活动,向全市人民征集 ...

  3. Thinkphp利用微信多客服消息推送取货二维码消息

    首先看微信官方的说法: 当用户主动发消息给公众号的时候(包括发送信息.点击自定义菜单.订阅事件.扫描二维码事件.支付成功事件.用户维权), 微信将会把消息数据推送给开发者,开发者在一段时间内(目前修改 ...

  4. cakephp 利用Pushapi扩展 进行app 消息推送

    public function push_designer_app($params) { $this->layout = false; $this->autoRender = false; ...

  5. java版Web Socket,实现消息推送

    # web socket是什么? WebSocket协议是基于TCP的一种新的网络协议. 它实现了浏览器与服务器全双工(full-duplex)通信,允许服务器主动发送信息给客户端. ## 用途 实时 ...

  6. 利用Kafka的Assign模式实现超大群组(10万+)消息推送

    引言 IM即时通信场景下,最重要的一个能力就是推送:在线的直接通过长连接网关服务转发,离线的通过APNS或者极光等系统进行推送.   本文主要是针对在线用户推送场景来进行总结和探讨:如何利用Kafka ...

  7. WebSocket实现Java后台消息推送

    1.什么是WebSocket WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端. 2.实现原理 在实现 ...

  8. SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)

     SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/si ...

  9. SSE(Server-sent events)技术在web端消息推送和实时聊天中的使用

    最近在公司闲着没事研究了几天,终于搞定了SSE从理论到实际应用,中间还是有一些坑的. 1.SSE简介 SSE(Server-sent events)翻译过来为:服务器发送事件.是基于http协议,和W ...

随机推荐

  1. Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)

    在前面章节的讨论中,我们一直基于一个假设:Linux中的时钟事件都是由一个周期时钟提供,不管系统中的clock_event_device是工作于周期触发模式,还是工作于单触发模式,也不管定时器系统是工 ...

  2. 附录D——自动微分(Autodiff)

    本文介绍了五种微分方式,最后两种才是自动微分. 前两种方法求出了原函数对应的导函数,后三种方法只是求出了某一点的导数. 假设原函数是$f(x,y) = x^2y + y +2$,需要求其偏导数$\fr ...

  3. 最近最久未使用页面淘汰算法———LRU算法(java实现)

    请珍惜小编劳动成果,该文章为小编原创,转载请注明出处. LRU算法,即Last Recently Used ---选择最后一次访问时间距离当前时间最长的一页并淘汰之--即淘汰最长时间没有使用的页 按照 ...

  4. Android 自定义ViewGroup手把手教你实现ArcMenu

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37567907 逛eoe发现这样的UI效果,感觉很不错,后来知道github上有这 ...

  5. ImageMagick简介、GraphicsMagick、命令行使用示例

    http://elf8848.iteye.com/blog/382528 ImageMagick资料 ------------------------------------------------- ...

  6. yum 出问题了

    今天用yum 安装ntp 的过程中用了 Ctrl+ z, 然后yum 再也不能使用了: error: rpmdb: BDB0113 Thread/process 6589/14060193936774 ...

  7. Python 员工信息管理系统

    学Python将近一个月了,第一次写了两百多行代码,一个很简单的脚本. 员工信息管理系统: 需求: 1.管理员账户能够增加,删除,修改,查询员工信息,并且设置管理员账户. 2.普通账户可以查看所有员工 ...

  8. Python 模块详解及import本质

    同在当前目录下的模块和包导入 模块定义 本质就是.py结尾的python文件. 用来从逻辑上组织python代码(变量,函数,类,逻辑) 文件名: test.py;  对应的模块名 : test 模块 ...

  9. 在Windows Server 2008 R2下搭建jsp环境(二)-mysql的下载安装

    个人推荐java开发过程中的数据库首选MYSQL,MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司.MySQL是一种关联数据库管理系统,关联数据库将数据保 ...

  10. bzoj 1210 [HNOI2004] 邮递员 插头dp

    插头dp板子题?? 搞了我一晚上,还tm全是抄的标程.. 还有高精,哈希混入,还是我比较弱,orz各种dalao 有不明白的可以去看原论文.. #include<cstdio> #incl ...