English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Java Socket Chat Room Programming (Part Two) Using Socket to Implement One-to-One Chat Room

In the previous article Java Socket Chat Room Programming (I) Using Socket to Implement Chat Message Push, we talked about how to use socket to pass messages between the server and the client to achieve the purpose of message push. Next, I will write how to make the server establish communication between clients and clients.

It is actually to establish a one-to-one chat communication.

The code for implementing message push in the previous article is slightly different, and it has been modified on top of it.

If there are no mentioned methods or classes, they are exactly the same as the previous one.

1The modification of the entity class (the entity class on the server side and the client side is the same)

1The UserInfoBean user information table

public class UserInfoBean implements Serializable {
private static final long serialVersionUID = 2L;
private long userId;// User id
private String userName;// Username
private String likeName;// Nickname
private String userPwd;// User password
private String userIcon;// User avatar
//Omit get and set methods
}

2The MessageBean chat information table

public class MessageBean implements Serializable {
private static final long serialVersionUID = 1L;
private long messageId;// Message ID
private long groupId;// Group ID
private boolean isGroup;// Is it a group message?
private int chatType;// Message type;1,text;2,image;3,short video;4,file;5,location information;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 id
private int friendId;//Target friend id
private 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 id
private 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 is the main chat service class, with modifications

public class ChatServer {
// socket service
private static ServerSocket server;
// Use ArrayList to store all the Sockets
public List<Socket> socketList = new ArrayList<>();
// Imitate the sockets stored in memory
public Map<Integer, Socket> socketMap = new HashMap();
// Imitate the user information stored 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 on port808Listen to customer requests
server = new ServerSocket(SocketUrls.PORT);
createMessage();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Create message management, keep receiving messages
*/
private void createMessage() {
try {
System.out.println("Waiting for user connection : ");
// Use accept() to block and wait for customer requests
Socket socket = server.accept();
// Save the incoming socket to the collection
socketList.add(socket);
System.out.println("User connected : ", + socket.getPort());
// Start a child thread to wait for another socket to join
new Thread(new Runnable() {
public void run() {
// Create another socket service to wait for other users to connect
createMessage();
}
}).start();
// Used to push messages to users by the server
getMessage();
// Obtain information from the client
BufferedReader bff = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// Read the information sent from the server
String line = null;
// Keep receiving the messages sent from the current socket in a loop
while (true) {
Thread.sleep(500);
// System.out.println("Content : ", + bff.readLine());
// Obtain client information
while ((line = bff.readLine()) != null) {
// Parse the entity class
MessageBean messageBean = gson.fromJson(line, MessageBean.class);
// Add the user information to the map, simulating the addition to the database and memory
// The entity class is stored in the database, and the socket is stored in memory, both with user id 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();
}
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Error : ", + e.getMessage());
}
}
/**
* Send message
*/
private void getMessage() {
new Thread(new Runnable() {
public void run() {
try {
String buffer;
while (true) {
// Input from console
BufferedReader string = new BufferedReader(new InputStreamReader(System.in));
buffer = string.readLine();
// Since readLine ends with a newline character, a newline is added at the end
buffer += "\n";
// Modify this 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"));-8"));
// Send data
output.flush();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
/**
* Simulate adding information into database and memory
* 
* @param messageBean
* @param scoket
*/
private void setChatMap(MessageBean messageBean, Socket scoket) {
// Store the user information
if (userMap != null && userMap.get(messageBean.getUserId()) == null) {
userMap.put(messageBean.getUserId(), getUserInfoBean(messageBean.getUserId()));
}
// Store the corresponding incoming socket
if (socketMap != null && socketMap.get(messageBean.getUserId()) == null) {
socketMap.put(messageBean.getUserId(), scoket);
}
}
/**
* Simulate database user information, creating 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);
// Since readLine ends with a newline character, a newline is added at the end
buffer += "\n";
try {
// Send information to the client
OutputStream output = socket.getOutputStream();
output.write(buffer.getBytes("utf-8"));-8"));
// Send data
output.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

3,(client code) Modification of LoginActivity login page can log in multiple people

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) {
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 the login status,1For the user,2Simulate communication between two users for another user
*
* @param name
* @param pwd
* @return
*/
private int getLogin(String name, String pwd) {
if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd)) {
return 0;//Incomplete 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)Modify the 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 a 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() {
//Start a thread to receive messages
receiveMessage();
}
/**
* 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 operations mimic the chat interface when a user clicks on a friend's chat, saving the user ID and the chat target user ID
if (status == 1) {//If it is a user1Then it points to the user2Chat
messageBean.setUserId(1);
messageBean.setFriendId(2);
} else if (status == 2) {//If it is a user2Then it points to the user1Chat
messageBean.setUserId(2);
messageBean.setFriendId(1);
}
ChatAppliaction.userInfoBean = userInfoBean;
}
/**
* Send 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 content to utf-8
String aaa = new String(str);
messageBean.setContent(aaa);
String messageJson = gson.toJson(messageBean);
/**
* Because the readLine() on the server side is a blocking read
* If it cannot read the newline character or the output stream ends, it will block there indefinitely
* Therefore, add a newline character at the end of the JSON message to inform the server that the message has been sent
* */
messageJson += "\n";
output.write(messageJson.getBytes("utf-8"));// New line print
output.flush(); // Refresh the output stream to make the Server receive the string immediately
}
e.printStackTrace();
Log.e("test", "Error:") + e.toString());
}
}
/**
* Receive messages, in a sub-thread
*/
private void receiveMessage() {
new Thread(new Runnable() {
@Override
public void run() {
try {
// To the local8080 port sends a client request
socket = new Socket(SocketUrls.IP, SocketUrls.PORT);
// Obtain 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());
// Obtain information from the client
BufferedReader bff = new BufferedReader(new InputStreamReader(input));
// Read the information sent from the server
String line;
while (true) {
Thread.sleep(500);
// Obtain client 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
}
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 message push logic to the single chat logic.

This code allows users1With users2Chat with each other, and the server will record their chat history. The server also has the function of message push.

The above is the Java Socket Chat Room Programming (Part Two) introduced by the editor for everyone, using socket to implement a single chat chat room, hoping it will be helpful to everyone. If you have any questions, please leave a message, and the editor will reply to everyone in time. Here, I also want to express my sincere gratitude to everyone for their support of the Yell Tutorial website!

Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email to report abuse, and provide relevant evidence. Once verified, this site will immediately delete the content suspected of infringement.)

You May Also Like