新聞中心
前言

在酒泉等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計、網(wǎng)站制作 網(wǎng)站設(shè)計制作按需策劃,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),全網(wǎng)營銷推廣,成都外貿(mào)網(wǎng)站制作,酒泉網(wǎng)站建設(shè)費用合理。
最近一周沒有發(fā)文章了,我在這里向大家說一聲抱歉。今天,我們來從零開始開發(fā)一款聊天室。好,我們現(xiàn)在就開始。
了解WebSocket
開發(fā)聊天室,我們需要用到WebSocket這個網(wǎng)絡(luò)通信協(xié)議,那么為什么會用到它呢?
我們首先來引用阮一峰大佬的一篇文章一段話:
- 初次接觸 WebSocket 的人,都會問同樣的問題:我們已經(jīng)有了 HTTP 協(xié)議,為什么還需要另一個協(xié)議?它能帶來什么好處?
- 答案很簡單,因為 HTTP 協(xié)議有一個缺陷:通信只能由客戶端發(fā)起。
- 舉例來說,我們想了解今天的天氣,只能是客戶端向服務(wù)器發(fā)出請求,服務(wù)器返回查詢結(jié)果。HTTP 協(xié)議做不到服務(wù)器主動向客戶端推送信息。
- 這種單向請求的特點,注定了如果服務(wù)器有連續(xù)的狀態(tài)變化,客戶端要獲知就非常麻煩。我們只能使用"輪詢":每隔一段時候,就發(fā)出一個詢問,了解服務(wù)器有沒有新的信息。最典型的場景就是聊天室。
- 輪詢的效率低,非常浪費資源(因為必須不停連接,或者 HTTP 連接始終打開)。因此,工程師們一直在思考,有沒有更好的方法。WebSocket 就是這樣發(fā)明的。
我們來借用MDN網(wǎng)站上的官方介紹總結(jié)一下:
WebSockets 是一種先進的技術(shù)。它可以在用戶的瀏覽器和服務(wù)器之間打開交互式通信會話。使用此API,您可以向服務(wù)器發(fā)送消息并接收事件驅(qū)動的響應(yīng),而無需通過輪詢服務(wù)器的方式以獲得響應(yīng)。
WebSocket 協(xié)議在2008年誕生,2011年成為國際標準。
WebSocket特點
服務(wù)器可以主動向客戶端推送信息,客戶端也可以主動向服務(wù)器發(fā)送信息,是真正的雙向平等對話,屬于服務(wù)器推送技術(shù)的一種。
建立在 TCP 協(xié)議之上,服務(wù)器端的實現(xiàn)比較容易。
與 HTTP 協(xié)議有著良好的兼容性。默認端口也是80和443,并且握手階段采用 HTTP 協(xié)議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務(wù)器。
數(shù)據(jù)格式比較輕量,性能開銷小,通信高效。
可以發(fā)送文本,也可以發(fā)送二進制數(shù)據(jù)。
沒有同源限制,客戶端可以與任意服務(wù)器通信。
協(xié)議標識符是ws(如果加密,則為wss),即ws對應(yīng)http,wss對應(yīng)https。服務(wù)器網(wǎng)址就是 URL。即ws://www.xx.com或wss://www.xx.com
WebSocket客戶端常用API
WebSocket 對象提供了用于創(chuàng)建和管理 WebSocket連接,以及可以通過該連接發(fā)送和接收數(shù)據(jù)的 API。
使用WebSocket()構(gòu)造函數(shù)來構(gòu)造一個WebSocket 。
屬性
1.WebSocket.onopen
用于指定連接成功后的回調(diào)函數(shù)。
2.WebSocket.onmessage
用于指定當從服務(wù)器接受到信息時的回調(diào)函數(shù)。
3.WebSocket.onclose
用于指定連接關(guān)閉后的回調(diào)函數(shù)。
4.WebSocket.onerror
用于指定連接失敗后的回調(diào)函數(shù)。
方法
1.WebSocket.close()
關(guān)閉當前鏈接。
2.WebSocket.send(data)
客戶端發(fā)送數(shù)據(jù)到服務(wù)器,對要傳輸?shù)臄?shù)據(jù)進行排隊。
客戶端舉例
- // Create WebSocket connection.
- const socket = new WebSocket('ws://localhost:8080'); // 這里的地址是服務(wù)器的websocket服務(wù)地址
- // Connection opened
- socket.onopen = function(evt) {
- console.log("Connection open ...");
- ws.send("Hello WebSockets!");
- };
- // Listen for messages
- socket.onmessage = function(evt) {
- console.log( "Received Message: " + evt.data);
- socket.close();
- };
- // Connection closed
- socket.onclose = function(evt) {
- console.log("Connection closed.");
- };
常用的WebSocket服務(wù)端
這里服務(wù)端我們使用Node.js,這里向大家介紹幾個常用的庫。
- ws
- socket.io
- nodejs-websocket
具體用法,大家可以上網(wǎng)瀏覽詳細文檔,這里就不一一介紹啦。不過在這篇文章中。我將會給大家使用ws與nodejs-websocket這兩個模塊來分別進行項目開發(fā)。
客戶端與服務(wù)端都介紹完啦!我們就趕快行動起來吧!
開發(fā)本地端(或局域網(wǎng))聊天室(第一種)
我們將基于Vue.js@3.0開發(fā)聊天室,原因是擁抱新技術(shù)。怎么搭建vue腳手架,這里就不介紹了,想必大家也會。我們直接就上代碼。
客戶端
在線人數(shù):{{ count }}
- v-for="(item, index) in chatArr"
- :key="index"
- class="chat-item"
- >
{{ item.txt }}
- {{ item.name.substring(item.name.length - 5, item.name.length) }}
- {{ item.name.substring(item.name.length - 5, item.name.length) }}
{{ item.txt }}
發(fā)送
至于樣式文件,這里我也貼出來。
- html,body{
- background-color: #e8e8e8;
- user-select: none;
- }
- ::-webkit-scrollbar {
- width: 8px;
- height: 8px;
- display: none;
- }
- ::-webkit-scrollbar-thumb {
- background-color: #D1D1D1;
- border-radius: 3px;
- -webkit-border-radius: 3px;
- border-left: 2px solid transparent;
- border-top: 2px solid transparent;
- }
- *{
- margin: 0;
- padding: 0;
- }
- .mine {
- justify-content: flex-end;
- }
- .other {
- justify-content: flex-start;
- }
- .mineBg {
- background: #98e165;
- }
- .otherBg {
- background: #fff;
- }
- .home {
- position: fixed;
- top: 0;
- left: 50%;
- transform: translateX(-50%);
- width: 100%;
- height: 100%;
- min-width: 360px;
- min-height: 430px;
- box-shadow: 0 0 24px 0 rgb(19 70 80 / 25%);
- }
- .count{
- height: 5%;
- display: flex;
- justify-content: center;
- align-items: center;
- background: #EEEAE8;
- font-size: 16px;
- }
- .content {
- width: 100%;
- height: 80%;
- background-color: #f4f4f4;
- overflow: hidden;
- }
- .footer {
- position: fixed;
- bottom: 0;
- width: 100%;
- height: 15%;
- background-color: #fff;
- }
- .footer textarea {
- width: 100%;
- height: 50%;
- background: #fff;
- border: 0;
- box-sizing: border-box;
- resize: none;
- outline: none;
- padding: 10px;
- font-size: 16px;
- }
- .send-box {
- display: flex;
- height: 40%;
- justify-content: flex-end;
- align-items: center;
- }
- .send {
- margin-right: 20px;
- cursor: pointer;
- border-radius: 3px;
- background: #f5f5f5;
- z-index: 21;
- font-size: 16px;
- padding: 8px 20px;
- }
- .send:hover {
- filter: brightness(110%);
- }
- .active {
- background: #98e165;
- color: #fff;
- }
- .chat-box {
- height: 100%;
- padding:0 20px;
- overflow-y: auto;
- }
- .chat-msg {
- display: flex;
- align-items: center;
- }
- .user {
- font-weight: bold;
- color: #fff;
- position: relative;
- word-wrap: break-word;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
- width: 60px;
- height: 60px;
- line-height: 60px;
- border-radius:8px ;
- text-align: center;
- }
- .msg {
- margin: 0 5px;
- max-width: 74%;
- white-space: normal;
- word-break: break-all;
- color: #333;
- border-radius: 8px;
- padding: 10px;
- text-align: justify;
- font-size: 16px;
- box-shadow: 0px 0px 10px #f4f4f4;
- }
- .chat-item {
- margin: 20px 0;
- animation: up-down 1s both;
- }
- @keyframes up-down {
- 0% {
- opacity: 0;
- transform: translate3d(0, 20px, 0);
- }
- 100% {
- opacity: 1;
- transform: none;
- }
- }
服務(wù)端
這里使用的是Node.js。
nodejs-websocket:websocket服務(wù)器和客戶端的nodejs模塊。
- const ws = require("nodejs-websocket");
- const server = ws.createServer((conn) => {
- conn.on("text", (str) => {
- broadcast(str);
- });
- conn.on("error", (err) => {
- console.log(err);
- });
- });
- server.listen(3000, function () {
- console.log("open");
- });
- // 群發(fā)消息
- function broadcast(data) {
- server.connections.forEach((conn) => {
- conn.sendText(data);
- });
- }
項目一覽
在線人數(shù)為零,這不是bug,是因為當時在本地端沒有做,只是放上了這個版塊。不過,在云服務(wù)端我已經(jīng)放上了這個功能。那么,我們來看一下吧。
開發(fā)云端聊天室(第二種)
客戶端?
在線人數(shù):{{ count }}
- v-for="(item, index) in chatArr"
- :key="index"
- class="chat-item"
- >
{{ item.txt }}
- {{ item.name.substring(item.name.length - 5, item.name.length) }}
- {{ item.name.substring(item.name.length - 5, item.name.length) }}
{{ item.txt }}
發(fā)送
樣式文件同本地端樣式,可以查看上方的代碼。
服務(wù)端
這里我使用了ws模塊,并且我也搭建了https服務(wù)器,并使用了更為安全的wss協(xié)議。接下來,我們來看下是怎么操作的。
- const fs = require("fs");
- const httpServ = require("https");
- const WebSocketServer = require("ws").Server; // 引用Server類
- const cfg = {
- port: 3456,
- ssl_key: "../../https/xxx.key", // 配置https所需的文件2
- ssl_cert: "../../https/xxx.crt", // 配置https所需的文件1
- };
- // 創(chuàng)建request請求監(jiān)聽器
- const processRequest = (req, res) => {
- res.writeHead(200);
- res.end("Websocket linked successfully");
- };
- const app = httpServ
- .createServer(
- {
- // 向server傳遞key和cert參數(shù)
- key: fs.readFileSync(cfg.ssl_key),
- cert: fs.readFileSync(cfg.ssl_cert),
- },
- processRequest
- )
- .listen(cfg.port);
- // 實例化WebSocket服務(wù)器
- const wss = new WebSocketServer({
- server: app,
- });
- // 群發(fā)
- wss.broadcast = function broadcast(data) {
- wss.clients.forEach(function each(client) {
- client.send(data);
- });
- };
- // 如果有WebSocket請求接入,wss對象可以響應(yīng)connection事件來處理
- wss.on("connection", (wsConnect) => {
- console.log("Server monitoring");
- wss.broadcast(wss._server._connections);
- wsConnect.on("message", (message) => {
- wss.broadcast(message);
- });
- wsConnect.on("close", function close() {
- console.log("disconnected");
- wss.broadcast(wss._server._connections);
- });
- });
我們在云服務(wù)上啟動命令。
啟動成功!
這里還沒有結(jié)束,因為你使用的是ip地址端口,必須轉(zhuǎn)發(fā)到域名上。所以我使用的nginx進行轉(zhuǎn)發(fā),配置如下參數(shù)。
- location /wsline/ {
- proxy_pass https://xxx:3456/;
- proxy_http_version 1.1;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "Upgrade";
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header Host $http_host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-Proto https;
- proxy_redirect off;
- }
那么,重啟云端服務(wù)器,看下效果。
項目一覽
那么,到這里一款云端聊天室就這么做成了,可以實時顯示在線人數(shù),這樣你就可以知道有多少人在這里跟你聊天。
結(jié)語
謝謝閱讀,希望我沒有浪費你的時間??赐晡恼铝?,那么趕快行動起來吧,開發(fā)一款屬于自己的聊天室。
網(wǎng)站標題:沉寂了一周,我開發(fā)了一個聊天室
網(wǎng)頁地址:http://www.5511xx.com/article/ccoddds.html


咨詢
建站咨詢
