




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第SpringBoot整合websocket實(shí)現(xiàn)即時(shí)通信聊天目錄一、技術(shù)介紹1.1客戶端WebSocket1.1.1函數(shù)1.1.2事件1.2服務(wù)端WebSocket二、實(shí)戰(zhàn)2.1、服務(wù)端2.1.1引入maven依賴2.1.2編寫配置類2.1.3編寫WebSocketService服務(wù)類2.1.4建立連接2.1.5關(guān)閉連接2.1.6發(fā)送消息2.1.7監(jiān)聽錯(cuò)誤2.2客戶端2.2.1主頁面2.2.1聊天頁面三、開源地址四、參考文獻(xiàn)
一、技術(shù)介紹
線上演示地址:http://chat.breez.work
實(shí)時(shí)通信(InstantMessaging,簡(jiǎn)稱IM)是一個(gè)實(shí)時(shí)通信系統(tǒng),允許兩人或多人使用網(wǎng)絡(luò)實(shí)時(shí)的傳遞文字消息、文件、語音與視頻交流。[4]
場(chǎng)景再現(xiàn):
微信聊天QQ聊天網(wǎng)站在線客服
1.1客戶端WebSocket
WebSocket對(duì)象提供了用于創(chuàng)建和管理WebSocket連接,以及可以通過該連接發(fā)送和接收數(shù)據(jù)的API。使用WebSocket()構(gòu)造函數(shù)來構(gòu)造一個(gè)WebSocket。[1]
構(gòu)造函數(shù)如下所示:
constwebSocket=WebSocket(url[,protocols])
例子如下:
constwebSocket=newWebSocket("ws://6:3688/ws/小明/翠花")
1.1.1函數(shù)
1、webSocket.send()
該函數(shù)用于向服務(wù)端發(fā)送一條消息,例子如下:
webSocket.send("Helloserver!");
2、webSocket.close()
該函數(shù)用于關(guān)閉客戶端與服務(wù)端的連接,例子如下:
webSocket.close();
1.1.2事件
1、webSocket.onopen
該事件用于監(jiān)聽客戶端與服務(wù)端的連接狀態(tài),如果客戶端與服務(wù)端連接成功則該事件觸發(fā),例子如下:
webSocket.onopen=function(event){
console.log("連接已經(jīng)建立,可以進(jìn)行通信");
};
2、webSocket.onclose
如果服務(wù)端與客戶端連接斷開,那么此事件出發(fā),例子如下:
webSocket.onclose=function(event){
console.log("連接已經(jīng)關(guān)閉");
};
3、webSocket:messageevent
該事件用于監(jiān)聽服務(wù)端向客戶端發(fā)送的消息,例子如下:
webSocket.addEventListener('message',function(event){
console.log('來自服務(wù)端的消息:',event.data);
});
4、webSocket:errorevent
如果客戶端與服務(wù)端發(fā)生錯(cuò)誤時(shí),那么此事件將會(huì)觸發(fā),例子如下:
webSocket.addEventListener('error',function(event){
console.log('連接出現(xiàn)錯(cuò)誤',event);
});
1.2服務(wù)端WebSocket
@ServerEndpoint用于聲明一個(gè)socket服務(wù),例子如下:
@ServerEndpoint(value="/ws/{userId}/{targetId}")
幾個(gè)重要的方法注解:
@OnOpen打開連接@OnClose監(jiān)聽關(guān)閉@OnMessage發(fā)送消息@OnError監(jiān)聽錯(cuò)誤
二、實(shí)戰(zhàn)
2.1、服務(wù)端
2.1.1引入maven依賴
dependency
groupIdorg.springframework.boot/groupId
artifactIdspring-boot-starter-websocket/artifactId
/dependency
2.1.2編寫配置類
@Configuration
publicclassWebSocketConfig{
@Bean
publicServerEndpointExporterserverEndpointExporter(){
returnnewServerEndpointExporter();
}
2.1.3編寫WebSocketService服務(wù)類
下面的userId代表發(fā)送者的ID號(hào),target代表發(fā)送目標(biāo)ID號(hào)。
@Component
@ServerEndpoint(value="/ws/{userId}/{target}")
publicclassWebSocketService{
//用于保存連接的用戶信息
privatestaticConcurrentHashMapString,SessionSESSION=newConcurrentHashMap();
//原子遞增遞減,用于統(tǒng)計(jì)在線用戶數(shù)
privatestaticAtomicIntegercount=newAtomicInteger();
//消息隊(duì)列,用于保存待發(fā)送的信息
privateQueueStringqueue=newLinkedBlockingDeque();
//onOpen()
//onClose()
//onMessage()
//onError()
}
2.1.4建立連接
建立連接之前,判斷用戶是否已經(jīng)連接,如果沒有連接,那么將用戶session信息保存到集合,然后計(jì)數(shù)器遞增。
@OnOpen
publicvoidonOpen(Sessionsession,@PathParam("userId")StringuserId){
if(!SESSION.containsKey(userId)){
SESSION.put(userId,session);
count.incrementAndGet();
}
2.1.5關(guān)閉連接
關(guān)閉連接的時(shí)候,將用戶session刪除和計(jì)數(shù)器遞減。
@OnClose
publicvoidonClose(@PathParam("userId")StringuserId){
SESSION.remove(userId);
count.decrementAndGet();
}
2.1.6發(fā)送消息
發(fā)送采用的方法是:session.getBasicRemote().sendText(你好
@OnMessage
publicvoidonMessage(Stringmessage,@PathParam("userId")StringuserId,@PathParam("target")Stringtarget)throwsIOException{
queue.add(message);
Sessions=SESSION.get(target);
if(s==null){
Sessionb=SESSION.get(userId);
b.getBasicRemote().sendText("對(duì)方不在線");
}else{
for(inti=0;iqueue.size();i++){
Stringmsg=queue.poll();
Messagem=newMessage();
m.setUserId(userId);
s.getBasicRemote().sendText(msg);
}
2.1.7監(jiān)聽錯(cuò)誤
出現(xiàn)錯(cuò)誤,刪除用戶session信息和計(jì)數(shù)器遞減
@OnError
publicvoidonError(Throwableerror,@PathParam("userId")StringuserId){
SESSION.remove(userId);
count.decrementAndGet();
error.printStackTrace();
}
2.2客戶端
本案例中客戶端采用Nuxt編寫,相關(guān)代碼如下
2.2.1主頁面
運(yùn)行截圖如圖所示:
template
div
div
div歡迎使用喵喵號(hào)聊天/div
/div
div
el-form:rules="rules"ref="formInline":inline="true":model="formInline"
el-form-itemlabel="我的喵喵號(hào)"prop="userId"
el-inputv-model="formInline.userId"placeholder="喵喵號(hào)"/el-input
/el-form-item
el-form-itemlabel="對(duì)方喵喵號(hào)"prop="targetId"
el-inputv-model="formInline.targetId"placeholder="喵喵號(hào)"/el-input
/el-form-item
el-form-item
el-buttontype="primary"@click="onSubmit('formInline')"聊一下/el-button
/el-form-item
/el-form
/div
/div
/template
script
exportdefault{
name:'IndexPage',
data(){
return{
formInline:{
userId:'',
targetId:''
rules:{
userId:[{
required:true,
message:'請(qǐng)輸入你的喵喵號(hào)',
trigger:'blur'
targetId:[{
required:true,
message:'請(qǐng)輸入對(duì)方喵喵號(hào)',
trigger:'blur'
methods:{
onSubmit(formName){
this.$refs[formName].validate((valid)={
if(valid){
this.$router.push({
name:'chat',
params:this.formInline
}else{
console.log('errorsubmit!!');
returnfalse;
created(){
/script
style
body{
background:url('../static/img/cat.jpg');
/style
2.2.1聊天頁面
運(yùn)行截圖如下:
小明
翠花
template
div
el-row:gutter="20"
div
div
div
我的喵喵號(hào):el-tagtype="warning"{{user.userId}}/el-tag
/div
div
對(duì)方喵喵號(hào):el-tagtype="success"{{user.targetId}}/el-tag
el-link@click="clearMsg()":underline="false"type="danger"清空消息/el-link
/div
/div
div
divv-for="(m,index)inmsgList":key="index++"
el-row:gutter="20"
divv-if="m.type===1"
el-avatarsrc="/0/88/03b0d39583f48206768a7534e55bcpng.png"/el-avatar
{{m.msg}}
/div
divv-if="m.type===2"
{{m.msg}}
el-avatarsrc="/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"/el-avatar
/div
divv-if="m.type===3"系統(tǒng)消息:{{m.msg}}/div
/el-row
/div
/div
/div
/el-row
el-row:gutter="5"
el-col:span="9":xs="9":sm="9":md="9":lg="9":xl="9"
el-input:disabled="msg_status"v-model="msg"placeholder="消息"/el-input
/el-col
el-col:span="2"
el-button@click="sendMessage()"type="primary"發(fā)送/el-button
/el-col
/el-row
/div
/template
script
exportdefault{
name:'ChatPage',
data(){
return{
url:'localhost:3688/ws/1001/1002',
msg:'',
socket:{},
msg_status:true,
msgList:[],
initList:[],
count:0,
user:{
userId:'',
targetId:''
created(){
constuserId=this.$route.params.userId
consttargetId=this.$route.params.targetId
if(userId!==undefinedtargetId!==undefined){
this.user.userId=userId
this.user.targetId=targetId
this.connect()
}else{
this.$router.push("/")
methods:{
//創(chuàng)建socket客戶端
connect(){
varthat=this
this.socket=newWebSocket("ws://6:3688/ws/"+this.user.userId+"/"+this.user.targetId);
this.socket.onclose=function(event){
that.$message('連接關(guān)閉');
this.socket.addEventListener('error',function(event){
that.$message.error('出現(xiàn)錯(cuò)誤');
//監(jiān)聽消息
this.socket.add
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 養(yǎng)魚合作協(xié)議書合同
- 甲方解除租賃合同協(xié)議書
- 生產(chǎn)安全承包合同協(xié)議書
- 餐飲食材配送合同協(xié)議書
- 關(guān)注女性健康,提升生命質(zhì)量課件
- 終止合同協(xié)議書條件
- 護(hù)考培訓(xùn)開班宣教
- 合同詐騙協(xié)議書
- 企業(yè)廚師合同協(xié)議書范本
- 住家保姆合同協(xié)議書
- 解除獨(dú)家合同范本
- 黑龍江省公安機(jī)關(guān)人民警察初級(jí)執(zhí)法資格測(cè)試題
- 醫(yī)師執(zhí)業(yè)注冊(cè)變更健康體檢表
- 2023年四川省綿陽市中考數(shù)學(xué)試卷
- 畢業(yè)設(shè)計(jì)調(diào)研總結(jié)報(bào)告
- 【數(shù)學(xué)】第八章 二元一次方程組單元測(cè)試卷 2023-2024學(xué)年人教版七年級(jí)數(shù)學(xué)下冊(cè)
- 數(shù)字貿(mào)易學(xué) 課件 第7章 智能制造
- 熱射病的防治與急救課件
- CATIAV5應(yīng)用教程-從機(jī)械設(shè)計(jì)到產(chǎn)品設(shè)計(jì)
- 小升初語文真題專項(xiàng)訓(xùn)練專題6+文學(xué)常識(shí)與名著閱讀(有解析)
- 新GCP醫(yī)療器械臨床試驗(yàn)知識(shí)試題(附含答案)
評(píng)論
0/150
提交評(píng)論