最近哥们在写微信小程序,其中有个需求是搭建一个聊天室,可多人聊天,可私聊,可发送图片。但是由于一直没有这方面相关的了解,于是慢慢的去看,去做,前期真的很困难,路子不好走,慢慢的再搭建。
先看看效果吧
1.websocket包搭建
我是用的Springboot + gradle搭建的,这是gradle配置
plugins {
id 'org.springframework.boot' version '2.1.7.RELEASE'
id 'io.spring.dependency-management' version '1.0.7.RELEASE'
id 'java'
}
group = 'org.ddd'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
//mavenCentral()
// �IJֿ��ַΪ���ڲֿ�
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web' // spring boot ����
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.0' // mybatis ����
compile group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version: '2.1.8.RELEASE'
compile("org.springframework.boot:spring-boot-starter-websocket")
runtimeOnly 'mysql:mysql-connector-java' // mysql ����
testImplementation 'org.springframework.boot:spring-boot-starter-test' // spring boot ����
compile "org.springframework.boot:spring-boot-starter-thymeleaf"
compile group: 'org.apache.directory.studio', name: 'org.apache.commons.lang', version: '2.6'
// https://mvnrepository.com/artifact/com.alibaba/fastjson
compile group: 'com.alibaba', name: 'fastjson', version: '1.2.58'
}
然后先给出java的websocket代码吧。
package DPI.service;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
//@ServerEndpoint("/websocket/{user}")
@ServerEndpoint(value = "/websocket/{user}/{otherUser}")
@Component
public class MyWebSocketServer {
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
private String user;
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(@PathParam(value="user") String param, Session session) {
System.out.println("连接成功");
this.session = session;
this.user = param;
webSocketSet.add(this); // 加入set中
addOnlineCount(); // 在线数加1
try {
sendMessage("连接成功");
} catch (IOException e) {
}
System.out.println("有新连接加入! 当前在线人数" + onlineCount);
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); // 从set中删除
subOnlineCount(); // 在线数减1
System.out.println("连接关闭");
System.out.println("有连接关闭! 当前在线人数" + onlineCount);
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session, @PathParam("user") String user, @PathParam("otherUser") String otherUser) {
System.out.println("来自" + user + "消息:" + message);
// try {
// session.getBasicRemote().sendText(message);
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
pushMessage(user, message, otherUser);
}
/**
* 消息推送
*
* @param message
* @param otherUser发送对象 otherUser为空则推送全部人员
*/
private void pushMessage(String user, String message, String otherUser) {
// TODO Auto-generated method stub
if (otherUser == null || "".equals(otherUser) || otherUser.equals("全部")) {
//群发消息
for (MyWebSocketServer item : webSocketSet) {
try {
item.sendMessage(user + ":" + message);
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
for (MyWebSocketServer item : webSocketSet) {
if (otherUser.equals(item.user)) {
try {
item.sendMessage(message);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
/**
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
/**
* 群发自定义消息
*/
public static void sendInfo(String message) throws IOException {
for (MyWebSocketServer item : webSocketSet) {
try {
item.sendMessage(message);
} catch (IOException e) {
continue;
}
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
MyWebSocketServer.onlineCount++;
}
public static synchronized void subOnlineCount() {
MyWebSocketServer.onlineCount--;
}
}
微信小程序端
js:
const app = getApp();
var inputVal = '';
var msgList = [];
var windowWidth = wx.getSystemInfoSync().windowWidth;
var windowHeight = wx.getSystemInfoSync().windowHeight;
var keyHeight = 0;
var socketOpen = false;
var frameBuffer_Data, session, SocketTask;
var url = 'ws://localhost:8000/websocket/';
var upload_url ='http://localhost:8000/file/upload'
/**
* 初始化数据
*/
function initData(that) {
inputVal = '';
msgList = [
{
speaker: 'others',
contentType: 'text',
content: '你好'
},
{
speaker: 'our',
contentType: 'text',
content: '你好'
},
{
speaker: 'others',
contentType: 'text',
content: '你有什么问题吗?'
}
]
that.setData({
msgList,
inputVal
})
}
Page({
/**
* 页面的初始数据
*/
data: {
scrollHeight: '100%',
inputBottom: 0,
otherName:"钟南山",
inputVal: '',
imgUrl: ''
},
changeOtherName:function(){
wx.setNavigationBarTitle({
title:this.data.otherName
})
},
getUserInput: function(e) {
this.data.inputVal = e.detail.value
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
initData(this);
this.setData({
cusHeadIcon: app.globalData.userInfo.avatarUrl,
});
this.changeOtherName();
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function() {
if (!socketOpen) {
this.webSocket()
}
},
onReady: function () {
var that = this;
SocketTask.onOpen(res => {
socketOpen = true;
console.log('监听 WebSocket 连接打开事件。', res)
})
SocketTask.onClose(onClose => {
console.log('监听 WebSocket 连接关闭事件。', onClose)
socketOpen = false;
this.webSocket()
})
SocketTask.onError(onError => {
console.log('监听 WebSocket 错误。错误信息', onError)
socketOpen = false
})
SocketTask.onMessage(onMessage => {
console.log(onMessage);
msgList.push({
speaker: 'others',
contentType: 'text',
content: onMessage.data
})
console.log('监听WebSocket接受到服务器的消息事件。服务器返回的消息', onMessage.data)
})
},
webSocket: function () {
// 创建Socket
SocketTask = wx.connectSocket({
url: url + "落花人独立" + '/ccc',
data: 'data',
header: {
'content-type': 'application/json'
},
method: 'post',
success: function (res) {
socketOpen = true;
console.log('WebSocket连接创建', res)
},
fail: function (err) {
wx.showToast({
title: '网络异常!',
})
console.log(err)
},
})
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
},
/**
* 获取聚焦
*/
focus: function(e) {
keyHeight = e.detail.height;
this.setData({
scrollHeight: (windowHeight - keyHeight) + 'px'
});
this.setData({
toView: 'msg-' + (msgList.length - 1),
inputBottom: keyHeight + 'px'
})
//计算msg高度
// calScrollHeight(this, keyHeight);
},
//失去聚焦(软键盘消失)
blur: function(e) {
this.setData({
scrollHeight: '100%',
inputBottom: 0
})
this.setData({
toView: 'msg-' + (msgList.length - 1)
})
},
submitTo: function () {
if (socketOpen) {
console.log('test');
// 如果打开了socket就发送数据给服务器
sendSocketMessage(this.data.inputVal)
}
msgList.push({
speaker: 'our',
contentType: 'text',
content: this.data.inputVal
})
inputVal = '';
this.setData({
msgList,
inputVal
});
},
upImg: function() {
var that = this;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
console.log(res);
that.data.imgUrl = res.tempFilePaths[0]
if (socketOpen) {
console.log('test');
// 如果打开了socket就发送数据给服务器
sendSocketMessage(this.data.imgUrl)
}
console.log('uploadFile');
wx.uploadFile({
filePath: res.tempFilePaths[0],
name: 'file',
url: "http://localhost:8000/upload",
formData: {
'user': '落花人独立'
},
header: {
"Content-Type": "multipart/form-data",
'accept': 'application/json'},
complete: (res) => {
console.log(res);
}
})
console.log('uploadFile完成');
}
})
},
/**
* 发送点击监听
*/
sendClick: function(e) {
if (socketOpen) {
console.log('test');
// 如果打开了socket就发送数据给服务器
sendSocketMessage(this.data.inputVal)
}
msgList.push({
speaker: 'our',
contentType: 'text',
content: e.detail.value
})
inputVal = '';
this.setData({
msgList,
inputVal
});
console.log(e);
},
/**
* 退回上一页
*/
toBackClick: function() {
wx.navigateBack({})
}
})
//通过 WebSocket 连接发送数据,需要先 wx.connectSocket,并在 wx.onSocketOpen 回调之后才能发送。
function sendSocketMessage(msg) {
var that = this;
console.log('通过 WebSocket 连接发送数据', JSON.stringify(msg))
SocketTask.send({
data: JSON.stringify(msg)
}, function (res) {
console.log('已发送', res)
})
}
wxml:
{{item.content}}
{{item.content}}
wxss:
page {
background-color: #f1f1f1;
}
.others{
display: flex;
padding: 2% 11% 2% 2%;
}
.head-img{
width: 71rpx;
height: 71rpx;
border-radius: 10rpx;
}
.triangle{
width: 4%;
height: 11vw;
display: flex;
align-items: center;
z-index: 9;
}
.other-tri{
margin-left: 0.5%;
}
.our-tri{
margin-right: 0.5%;
}
.our{
display: flex;
justify-content: flex-end;
padding: 2% 2% 2% 11%;
}
.input-room {
width: 100%;
height: 10%;
border-top: 1px solid #cdcdcd;
background-color: #f1f1f1;
position: fixed;
bottom: 0;
display: flex;
align-items: center;
z-index: 20;
}
input {
width: 76%;
height: 58%;
background-color: #fff;
border-radius: 40rpx;
margin-left: 2%;
padding: 0 3%;
font-size: 28rpx;
color: #444;
}
.left-msg {
font-size: 35rpx;
color: #444;
padding: 2.5% 2.5%;
background-color: #fff;
margin-left: -1%;
border-radius: 10rpx;
z-index: 10;
}
.right-msg {
font-size: 35rpx;
color: #444;
padding: 2.5% 2.5%;
background-color: #96EB6A;
margin-right: -1%;
border-radius: 10rpx;
z-index: 10;
}
.user_input_text {
width: 45px;
height: 34px;
font-size: 10px;
line-height: 21px;
padding-right: 18px;
margin-right: 7px;
border-radius: 11px;
}
如果帮助到你,麻烦请点个赞~~
整个项目暂时还没做完了,我会放到gitee上开源共享!