實時聊天室之WebSocket實戰
實時聊天室之WebSocket實戰
WebSocket 是一種在單個TCP 連接上進行全雙工通訊的網絡通信協議。
前言
如果要實現像微信聊天一樣的功能,在組網內進行通信顯然是不夠的,所以軟總線並不作用與這種遠距離傳輸。如果我們要完成微信的聊天功能,傳統的方法就是利用webSocket借助服務器進行全雙工通信。
WebSocket是什麼?
WebSocket 是一種在單個TCP 連接上進行全雙工通訊的網絡通信協議。
在以前沒有webSocket的時候,大家都用HTTP協議進行網絡通信,但是HTTP協議是一個無狀態,無連接,單向的應用層協議,因此只能讓客戶端對服務端進行單向請求,服務端無法主動向客戶端發送消息,導致了像實時聊天這種業務開展起來比較困難。
有開發者就使用HTTP進行長輪詢的方案,也就是說需要HTTP在一段時間內必須一直保持連接請求,以獲取最新的服務器的消息。這樣顯然效率低下,而且非常浪費資源。
因此就誕生了WebSocket,只需要進行一次連接,就可以一直保持全雙工的通信狀態。
Demo展示
下面我們就來用官方提供的WebSocket接口實現一個簡易實時聊天室的Demo。效果如下:
代碼實現
可以看到官方文檔的接口說明,我們只需要簡單用到幾個接口就可以實現我們的業務需求了。
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/websocket-connection-0000001333321005。
1、申請網絡權限
在config.json文件裡面註冊網絡權限,該權限允許程序打開網絡套接字,進行網絡連接。
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
- 1.
- 2.
- 3.
- 4.
- 5.
2、導入webSocket模塊
import webSocket from '@ohos.net.webSocket';
- 1.
3、創建webSocket對象
接著我們調用createWebSocket()接口生成一個webSocket對象,並且保存起來。
let ws = webSocket.createWebSocket();
- 1.
4、連接webSocket通道
調用connect()接口進行連接。這裡需要一個URL作為參數傳入,在這個demo中,直接用了一個以前開發好的服務器接口進行調用,但是不對外開放,因此大家只需要將自己開發好的接口地址放到”wsURL“內即可。
onInit() {
let that = this;
ws.connect("wsURL", (err, value) => {
if (!err) {
console.log("xxx---connect success");
} else {
console.log("xxx---connect fail, err:" + JSON.stringify(err));
}
});
},
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
5、订阅通道内消息更新
这里我们调用on( type:‘message’ )接口进行消息监听,这里要注意的是服务端传递过来的是字符串类型,所以如果消息是JSON对象,则需要用JSON.parse()进行解析,还原成JSON对象。
onInit() {
let that = this;
ws.on('message', (err, value) => {
console.log("xxx---on message, message:" + value);
//传递的是序列化后的字符串,需要解序列化为JSON对象
let dataObj = JSON.parse(value)
console.log("xxx---parse success---postId: "+dataObj.postId+",message:"+dataObj.message)
that.message.push(dataObj)
console.log("xxx---check message: "+JSON.stringify(that.message))
});
},
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
6、发送消息
紧接着调用send()接口进行消息的发送,这里注意,如果要传递的是JSON对象,要使用JSON.stringify()进行序列化操作, 保证我们传递的是流字符串的形式。
在该接口的回调中,我们也可以打印出来,看看消息是否发送成功。
sendMessage(){
let that = this;
let data = {
postId:that.id,
message:that.sendMes
}
let dataStr = JSON.stringify(data)
ws.send(dataStr, (err, value) => {
if (!err) {
console.log("xxx---send success");
} else {
console.log("xxx---send fail, err:" + JSON.stringify(err));
}
});
that.message.push(data)
},
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
7、隐藏标题栏
细心的小伙伴就会发现,我的demo展示的黑色标题栏不见了,其实是可以隐藏掉的,只需要在config.json文件中module.abilities下添加几行代码即可。
"metaData":{
"customizeData":[
{
"name": "hwc-theme",
"value": "androidhwext:style/Theme.Emui.NoTitleBar",
"extra":""
}
]
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
8、样式设计
接着就是简单设计一下界面样式,把获取到的消息渲染出来就完成啦。
<div class="container">
<div style="width: 100%;height: 8%;color: #ff86868a;font-size: 25px;justify-content: center;position: absolute;">
<text style="top: 10px;">
实时聊天室
</text>
</div>
<list style="height: 80%;">
<list-item for="{{message}}" class="{{$item.postId==id?'listItemRight':'listItemLeft'}}" >
<div class="listItemDiv" >
<text style="padding:5px;border-radius: 10px;font-size: 20px;margin: 5px;max-width: 70%;">
{{$item.message}}
</text>
</div>
</list-item>
</list>
<div style="position: absolute;left:10px;bottom: 20px;">
<textarea id="textarea" class="textarea" extend="true"
placeholder="请输入聊天信息"
onchange="inputChange" >
</textarea>
<button style="width: 75px;height: 50px;margin-left: 10px;background-color: #ff4848f5;" onclick="sendMessage"> 发送 </button>
</div>
</div>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
}
.textarea {
placeholder-color: gray;
width: 70%;
}
.listItemDiv{
background-color: #ff87f3d0;
border-radius: 10px;
}
.listItemLeft{
margin: 10px;
width: 100%;
justify-content: flex-start;
}
.listItemRight{
margin: 10px;
width: 100%;
justify-content: flex-end;
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
文章相关附件可以点击下面的原文链接前往下载:
https://ost.51cto.com/resource/2210。