In the previous article Java Socket Chat Room Programming (1) Using socket to implement chat message push, we talked about how to use socket to make messages pass between the server and the client to achieve the purpose of pushing messages. Next, I will write about how to enable the server to establish communication between the client and the client.
In fact, it is to establish a one-to-one chat communication.
It is somewhat different from the previous code that implemented message push, and it was modified on it.
If the methods or classes are not mentioned, they are exactly the same as in the previous article.
1. Modify the entity class (the entity class on the server and client is the same)
1. UserInfoBean User Information Table
public class UserInfoBean implements Serializable {private static final long serialVersionUID = 2L;private long userId;// User idprivate String userName;// User name private String likeName;// Nickname private String userPwd;// User password private String userIcon;// User avatar// Omit get and set methods}2. MessageBean Chat Information Table
public class MessageBean implements Serializable {private static final long serialVersionUID = 1L;private long messageId;// Message idprivate long groupId;// Group idprivate boolean isGoup;// Whether it is a group message private int chatType;// Message type;1, text;2, picture;3, short video;4, file;5, geographical location;6, voice;7, video call private String content;// Text message content private String errorMsg;// Error message private int errorCode;// Error code private int userId;//User idprivate int friendId;//Target friend idprivate MessageFileBean chatFile;//Message attachment//Omit get and set methods}3. MessageFileBean message attachment table
public class MessageFileBean implements Serializable {private static final long serialVersionUID = 3L;private int fileId;//file idprivate String fileName;//file name private long fileLength;//file length private Byte[] fileByte;//file content private String fileType;//file type private String fileTitle;//file header name//omit get and set methods}2. (Server side code modification) ChatServer's main chat service class, modified
public class ChatServer {// socket service private static ServerSocket server;// Use ArrayList to store all Socketpublic List<Socket> socketList = new ArrayList<>();// Imitate socketpublic Map<Integer, Socket> socketMap = new HashMap();// Imitate user information saved in the database public Map<Integer, UserInfoBean> userMap = new HashMap();public Gson gson = new Gson();/*** Initialize socket service*/public void initServer() {try {// Create a ServerSocket to listen to customer requests on port 8080 server = new ServerSocket(SocketUrls.PORT);createMessage();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** Create message management and keep receiving messages*/private void createMessage() {try {System.out.println("Waiting for user access: ");// Use accept() to block waiting for customer requests Socket socket = server.accept();// Save the linked socket to the collection socketList.add(socket);System.out.println("User Access: " + socket.getPort());// Open a child thread to wait for another socket to join new Thread(new Runnable() {public void run() {// Create a socket service again waiting for other users to access createMessage();}}).start();// Used to push messages to the user getMessage();// Get information from the client BufferedReader bff = new BufferedReader(new InputStreamReader(socket.getInputStream()));// Read the sent server information String line = null;// Looping to receive messages from the current socket while (true) {Thread.sleep(500);// System.out.println("Content: " + bff.readLine());// Get the client's information while ((line = bff.readLine()) != null) {// parse the entity class MessageBean messageBean = gson.fromJson(line, MessageBean.class);// Add user information into the map, imitate it into the database and memory// The entity class is stored in the database and the socket is stored in the memory. The user id is used as the reference setChatMap(messageBean, socket);// Forward the message sent by the user to the target friend getFriend(messageBean);System.out.println("User: " + userMap.get(messageBean.getUserId()).getUserName());System.out.println("Content: " + messageBean.getContent());}}// server.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("Error: " + e.getMessage());}}/*** Send a message*/private void getMessage() {new Thread(new Runnable() {public void run() {try {String buffer; while (true) {// Enter BufferedReader from the console strin = new BufferedReader(new InputStreamReader(System.in));buffer = strin.readLine();// Because readLine uses a newline as the end point, add a newline buffer at the end += "/n";// Here it is modified to push messages to all users connected to the server for (Socket socket : socketMap.values()) {OutputStream output = socket.getOutputStream();output.write(buffer.getBytes("utf-8"));// Send data output.flush();}}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}).start();}/*** Simulate adding information to the database and memory* * @param messageBean* @param scoket*/private void setChatMap(MessageBean messageBean, Socket scoket) {// Save the user information if (userMap != null && userMap.get(messageBean.getUserId()) == null) {userMap.put(messageBean.getUserId(), getUserInfoBean(messageBean.getUserId()));}// Save the corresponding linked socket if (socketMap != null && socketMap.get(messageBean.getUserId()) == null) {socketMap.put(messageBean.getUserId(), scoket);}}/*** Simulate the user information of the database, create user information with different ids here* * @param userId* @return*/private UserInfoBean getUserInfoBean(int userId) {UserInfoBean userInfoBean = new UserInfoBean();userInfoBean.setUserIcon("User Avatar");userInfoBean.setUserId(userId);userInfoBean.setUserName("admin");userInfoBean.setUserPwd("123123132a");return userInfoBean;}/*** Forward the message to the target friend* * @param messageBean*/private void getFriend(MessageBean messageBean) {if (socketMap != null && socketMap.get(messageBean.getFriendId()) != null) {Socket socket = socketMap.get(messageBean.getFriendId());String buffer = gson.toJson(messageBean);// Because readLine is the end point with a newline, add a newline buffer at the end += "/n";try {// Send message to the client OutputStream output = socket.getOutputStream();output.write(buffer.getBytes("utf-8"));// Send data output.flush();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}}}3. (Client Code) LoginActivity login page modification can log in to multiple people
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) {int status = getLogin(chat_name_text.getText().toString().trim(), chat_pwd_text.getText().toString().trim());if (status == -1 || status == 0) {Toast.makeText(LoginActivity.this, "Password Error", Toast.LENGTH_LONG).show();return;}getChatServer(getLogin(chat_name_text.getText().toString().trim(), chat_pwd_text.getText().toString().trim()));Intent intent = new Intent(LoginActivity.this, MainActivity.class);startActivity(intent);finish();}});}/*** Return to the login status, 1 is the user and 2 is the other user. Here, two users are simulated to communicate with each other** @param name* @param pwd* @return*/private int getLogin(String name, String pwd) {if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd)) {return 0;//No full password entered} else if (name.equals("admin") && pwd.equals("1")) {return 1;//User1} else if (name.equals("admin") && pwd.equals("2")) {return 2;//User2} else {return -1;//Password error}}/*** Instantiate a chat service** @param status*/private void getChatServer(int status) {ChatAppliaction.chatServer = new ChatServer(status);}}4. (Client Code) Modification of ChatServer Chat Service Code Logic
public class ChatServer {private Socket socket;private Handler handler;private MessageBean messageBean;private Gson gson = new Gson();// Get the output stream from the Socket object and construct the PrintWriter object PrintWriter printWriter;InputStream input;OutputStream output;DataOutputStream dataOutputStream;public ChatServer(int status) {initMessage(status);initChatServer();}/*** Message queue, used to pass messages** @param handler*/public void setChatHandler(Handler handler) {this.handler = handler;}private void initChatServer() {//Open thread to receive messages receivedMessage();}/*** Initialize user information*/private void initMessage(int status) {messageBean = new MessageBean();UserInfoBean userInfoBean = new UserInfoBean();userInfoBean.setUserId(2);messageBean.setMessageId(1);messageBean.setChatType(1);userInfoBean.setUserName("admin");userInfoBean.setUserPwd("123123123a");//The following operation imitates when the user clicks on a chat interface expanded by a friend, the user id and the chat target user idif (status == 1) {//If it is user 1, then he points to user 2 to chat messageBean.setUserId(1);messageBean.setFriendId(2);} else if (status == 2) {//If it is user 2, then he will point to user 1 to chat messageBean.setUserId(2); messageBean.setFriendId(1);}ChatAppliaction.userInfoBean = userInfoBean;}/*** Send a message** @param contentMsg*/public void sendMessage(String contentMsg) {try {if (socket == null) {Message message = handler.obtainMessage();message.what = 1;message.obj = "The server has been closed";handler.sendMessage(message);return;}byte[] str = contentMsg.getBytes("utf-8");//Convert the content to utf-8String aaa = new String(str); messageBean.setContent(aaa);String messageJson = gson.toJson(messageBean);/*** Because the readLine() on the server is blocking reading* If it cannot read the newline character or the output stream ends, it will be blocked there* So a newline character is added at the end of the json message to tell the server that the message has been sent* */messageJson += "/n";output.write(messageJson.getBytes("utf-8"));// Print newline character output.flush(); // Refresh the output stream so that the Server receives the string immediately} catch (Exception e) {e.printStackTrace();Log.e("test", "Error:" + e.toString());}}/*** Receive the message and in the child thread */private void receiveMessage() {new Thread(new Runnable() {@Overridepublic void run() {try {// Send a client request to the native port 8080 socket = new Socket(SocketUrls.IP, SocketUrls.PORT);// Get the input stream from the Socket object and construct the corresponding BufferedReader object printWriter = new PrintWriter(socket.getOutputStream());input = socket.getInputStream();output = socket.getOutputStream();dataOutputStream = new DataOutputStream(socket.getOutputStream());// Get information from the client BufferedReader bff = new BufferedReader(new InputStreamReader(input));// Read the sent server information String line; while (true) {Thread.sleep(500);// Get the client's information while ((line = bff.readLine()) != null) {Log.i("socket", "Content: " + line);MessageBean messageBean = gson.fromJson(line, MessageBean.class);Message message = handler.obtainMessage();message.obj = messageBean.getContent();message.what = 1;handler.sendMessage(message);}if (socket == null)break;}output.close();//Close Socket output stream input.close();//Close Socket input stream socket.close();//Close Socket} catch (Exception e) {e.printStackTrace();Log.e("test", "Error:" + e.toString());}}}).start();}public Socket getSocekt() {if (socket == null) return null;return socket;}}}In this way, the code logic has been modified from the logic of message push to the logic of single chat.
This code allows user 1 and user 2 to chat with each other, and the server will record the chat history between them. And the server also has the function of message push.
The above is the Java Socket chat room programming introduced to you by the editor (II) using socket to implement a single chat room. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support to Wulin.com website!