国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Java > 正文

Java Socket聊天室編程(一)之利用socket實(shí)現(xiàn)聊天之消息推送

2019-11-26 13:48:53
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

相關(guān)閱讀:Java Socket聊天室編程(二)之利用socket實(shí)現(xiàn)單聊聊天室

網(wǎng)上已經(jīng)有很多利用socket實(shí)現(xiàn)聊天的例子了,但是我看過(guò)很多,多多少有一些問(wèn)題存在。

這里我將實(shí)現(xiàn)一個(gè)比較完整的聊天例子,并解釋其中的邏輯。

由于socket這一塊比較大,所以我將分出幾篇來(lái)寫一個(gè)比較完整的socket例子。

這里我們先來(lái)實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的,服務(wù)器與客戶端通訊,實(shí)現(xiàn)消息推送的功能。

目的:服務(wù)器與客戶端建立連接,客戶端可以向服務(wù)器發(fā)送消息,服務(wù)器可以向客戶端推送消息。

1,使用java建立socket聊天服務(wù)器

1,SocketUrls 確定ip地址和端口號(hào)

public class SocketUrls{// ip地址public final static String IP = "192.168.1.110";// 端口號(hào)public final static int PORT = 8888;}

2,Main 程序的入口

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

3,Bean 實(shí)體類

用戶信息 UserInfoBean

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

聊天信息 MessageBean

public class MessageBean extends UserInfoBean {private long messageId;// 消息idprivate long groupId;// 群idprivate boolean isGoup;// 是否是群消息private int chatType;// 消息類型;1,文本;2,圖片;3,小視頻;4,文件;5,地理位置;6,語(yǔ)音;7,視頻通話private String content;// 文本消息內(nèi)容private String errorMsg;// 錯(cuò)誤信息private int errorCode;// 錯(cuò)誤代碼//省略get/set方法}

4,ChatServer 聊天服務(wù),最主要的程序

public class ChatServer {// socket服務(wù)private static ServerSocket server;public Gson gson = new Gson();/*** 初始化socket服務(wù)*/public void initServer() {try {// 創(chuàng)建一個(gè)ServerSocket在端口8080監(jiān)聽(tīng)客戶請(qǐng)求server = new ServerSocket(SocketUrls.PORT);createMessage();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** 創(chuàng)建消息管理,一直接收消息*/private void createMessage() {try {System.out.println("等待用戶接入 : ");// 使用accept()阻塞等待客戶請(qǐng)求Socket socket = server.accept();System.out.println("用戶接入 : " + socket.getPort());// 開(kāi)啟一個(gè)子線程來(lái)等待另外的socket加入new Thread(new Runnable() {public void run() {createMessage();}}).start();// 向客戶端發(fā)送信息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) {// 從控制臺(tái)輸入BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));buffer = strin.readLine();// 因?yàn)閞eadLine以換行符為結(jié)束點(diǎn)所以,結(jié)尾加入換行buffer += "/n";output.write(buffer.getBytes("utf-8"));// 發(fā)送數(shù)據(jù)output.flush();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}).start();// 讀取發(fā)來(lái)服務(wù)器信息String line = null;// 循環(huán)一直接收當(dāng)前socket發(fā)來(lái)的消息while (true) {Thread.sleep(500);// System.out.println("內(nèi)容 : " + bff.readLine());// 獲取客戶端的信息while ((line = bff.readLine()) != null) {MessageBean messageBean = gson.fromJson(line, MessageBean.class);System.out.println("用戶 : " + messageBean.getUserName());System.out.println("內(nèi)容 : " + messageBean.getContent());}}// server.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("錯(cuò)誤 : " + e.getMessage());}}}

2,Android 端作為移動(dòng)端連接服務(wù)器

1,appliaction 實(shí)例化一個(gè)全局的聊天服務(wù)

public class ChatAppliaction extends Application {public static ChatServer chatServer;public static UserInfoBean userInfoBean;@Overridepublic void onCreate() {super.onCreate();}}

2,ip地址和端口號(hào)和服務(wù)器保持一致

3,聊天實(shí)力類同服務(wù)器端一樣

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"><EditTextandroid:id="@+id/chat_name_text"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="用戶名"android:text="admin"/><EditTextandroid:id="@+id/chat_pwd_text"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="密碼"android:text="123123123a"android:inputType="numberPassword" /><Buttonandroid: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"><ScrollViewandroid:id="@+id/scrollView"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="0.9"><LinearLayoutandroid:id="@+id/chat_ly"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"></LinearLayout></ScrollView><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><EditTextandroid:id="@+id/chat_et"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="0.8" /><Buttonandroid:id="@+id/send_btn"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="0.2"android:text="發(fā)送" /></LinearLayout></LinearLayout>

5,LoginActivity 登陸

public class LoginActivity extends AppCompatActivity {private EditText chat_name_text, chat_pwd_text;private Button chat_login_btn;@Overrideprotected 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() {@Overridepublic 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);@Overrideprotected 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() {@Overridepublic void onClick(View v) {ChatAppliaction.chatServer.sendMessage(chat_et.getText().toString().trim());chat_ly.addView(initRightView(chat_et.getText().toString().trim()));}});//添加消息接收隊(duì)列ChatAppliaction.chatServer.setChatHandler(new Handler() {@Overridepublic void handleMessage(Message msg) {if (msg.what == 1) {//發(fā)送回來(lái)消息后,更新uichat_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對(duì)象得到輸出流,并構(gòu)造PrintWriter對(duì)象PrintWriter printWriter;InputStream input;OutputStream output;DataOutputStream dataOutputStream;public ChatServer() {initMessage();initChatServer();}/*** 消息隊(duì)列,用于傳遞消息** @param handler*/public void setChatHandler(Handler handler) {this.handler = handler;}private void initChatServer() {//開(kāi)個(gè)線程接收消息receiveMessage();}/*** 初始化用戶信息*/private void initMessage() {messageBean = new MessageBean();messageBean.setUserId(1);messageBean.setMessageId(1);messageBean.setChatType(1);messageBean.setUserName("admin");ChatAppliaction.userInfoBean = messageBean;}/*** 發(fā)送消息** @param contentMsg*/public void sendMessage(String contentMsg) {try {if (socket == null) {Message message = handler.obtainMessage();message.what = 1;message.obj = "服務(wù)器已經(jīng)關(guān)閉";handler.sendMessage(message);return;}byte[] str = contentMsg.getBytes("utf-8");//將內(nèi)容轉(zhuǎn)utf-8String aaa = new String(str);messageBean.setContent(aaa);String messageJson = gson.toJson(messageBean);/*** 因?yàn)榉?wù)器那邊的readLine()為阻塞讀取* 如果它讀取不到換行符或者輸出流結(jié)束就會(huì)一直阻塞在那里* 所以在json消息最后加上換行符,用于告訴服務(wù)器,消息已經(jīng)發(fā)送完畢了* */messageJson += "/n";output.write(messageJson.getBytes("utf-8"));// 換行打印output.flush(); // 刷新輸出流,使Server馬上收到該字符串} catch (Exception e) {e.printStackTrace();Log.e("test", "錯(cuò)誤:" + e.toString());}}/*** 接收消息,在子線程中*/private void receiveMessage() {new Thread(new Runnable() {@Overridepublic void run() {try {// 向本機(jī)的8080端口發(fā)出客戶請(qǐng)求socket = new Socket(SocketUrls.IP, SocketUrls.PORT);// 由Socket對(duì)象得到輸入流,并構(gòu)造相應(yīng)的BufferedReader對(duì)象printWriter = new PrintWriter(socket.getOutputStream());input = socket.getInputStream();output = socket.getOutputStream();dataOutputStream = new DataOutputStream(socket.getOutputStream());// 從客戶端獲取信息BufferedReader bff = new BufferedReader(new InputStreamReader(input));// 讀取發(fā)來(lái)服務(wù)器信息String line;while (true) {Thread.sleep(500);// 獲取客戶端的信息while ((line = bff.readLine()) != null) {Log.i("socket", "內(nèi)容 : " + line);Message message = handler.obtainMessage();message.obj = line;message.what = 1;handler.sendMessage(message);}if (socket == null)break;}output.close();//關(guān)閉Socket輸出流input.close();//關(guān)閉Socket輸入流socket.close();//關(guān)閉Socket} catch (Exception e) {e.printStackTrace();Log.e("test", "錯(cuò)誤:" + e.toString());}}}).start();}}

寫到這里,已經(jīng)完成了所有的代碼。

這個(gè)demo可以實(shí)現(xiàn)手機(jī)端向服務(wù)器發(fā)送消息,服務(wù)器向手機(jī)端發(fā)送消息。

這個(gè)demo可以算是推送功能,不過(guò)真正的推送沒(méi)有這么簡(jiǎn)單。作為一個(gè)socket的入門了解,可以從中看到socket編程的思想。

以上所述是小編給大家介紹的Java Socket聊天室編程(一)之利用socket實(shí)現(xiàn)聊天之消息推送,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)武林網(wǎng)網(wǎng)站的支持!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 鄂伦春自治旗| 汨罗市| 襄垣县| 陈巴尔虎旗| 同江市| 新干县| 竹北市| 米脂县| 康定县| 南川市| 泸定县| 商河县| 拜城县| 崇仁县| 和林格尔县| 东方市| 页游| 金坛市| 基隆市| 古田县| 旬邑县| 牟定县| 玉山县| 敖汉旗| 荆门市| 兴宁市| 辛集市| 柞水县| 黄石市| 平江县| 静宁县| 瓦房店市| 安徽省| 尼木县| 云浮市| 介休市| 会泽县| 沅陵县| 类乌齐县| 黄山市| 永善县|