1. WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
2.示例代码
前端
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>WebSocketTest</title> <script type="text/javascript"> var ws; if ("WebSocket" in window) { console.log("您的浏览器支持 WebSocket!"); ws = new WebSocket("ws://localhost:8090"); ws.onopen = function () { ws.send("发送数据"); console.log("数据发送中..."); }; ws.onmessage = function (evt) { var received_msg = evt.data; console.log("数据已接收:", received_msg); }; ws.onclose = function () { console.log("连接已关闭..."); }; ws.onerror = function (err) { console.log("error...",err); }; } else { console.log("您的浏览器不支持 WebSocket!"); } function WebSocketTest() { if(ws.close){ ws.close(); } } </script> </head> <body> <div id="sse"> <a href="javascript:WebSocketTest()">关闭 WebSocket</a> </div> </body> </html>
前端 + node : 聊天室
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> <style> p { color: orange; padding: 5px 10px; margin: 0; } .user_msg { color: #ccc; } #messages { background: #000; } </style> </head> <body> <div class="vertical-center"> <div class="container"> <ul id="messages" class="list-unstyled"></ul> <hr /> <form role="form" id="chat_form" onsubmit="sendMessage(); return false;"> <div class="form-group"> <input class="form-control" type="text" id="message" name="message" placeholder="Type text to echo in here" value="" autofocus /> </div> <button type="button" id="send" class="btn btn-primary" onclick="sendMessage();"> Send Message </button> </form> <div class="form-group"><span>nikename:</span><input id="name" type="text" /> <button class="btn btn-sm btn-info" onclick="changName();">change</button></div> </div> </div> <script> var nickname = ""; var ws = new WebSocket("ws://localhost:8090"); ws.onopen = function (e) { console.log('Connection to server opened'); } ws.onmessage = function (e) { var data = JSON.parse(e.data); nickname = data.nickname; appendLog(data.type, data.nickname, data.message); console.log("ID: [%s] = %s", data.id, data.message); } ws.onclose = function (e) { appendLog("Connection closed"); console.log("Connection closed"); } function changName() { var name = $("#name").value; if (ws.readyState === WebSocket.OPEN) { ws.send("/nick " + name); } } function appendLog(type, nickname, message) { if (typeof message == "undefined") return; var messages = document.getElementById('messages'); var messageElem = document.createElement("li"); var preface_label; var message_text; if (type === 'notification') { preface_label = `<span class="label label-warning"><i class="glyphicon glyphicon-plus"></i></span>`; message_text = `<p>${preface_label} ${message}</p>` } else if (type == 'nick_update') { preface_label = `<span class="label label-warning"><i class="glyphicon glyphicon-bullhorn"></i></span>`; message_text = `<p>${preface_label} ${message}</p>` } else { preface_label = `<span class="label label-info">${nickname}</span>`; message_text = `<p class="user_msg">${preface_label} ${message}</p>` } messageElem.innerHTML = message_text; messages.appendChild(messageElem); } function sendMessage() { var messageField = document.getElementById('message'); if (ws.readyState === WebSocket.OPEN) { ws.send(messageField.value); } messageField.value = ''; messageField.focus(); } function $(s) { return document.querySelector(s) } // ajax({ // url:'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg', // method:'get', // async:true, // success:function(data){ // console.log('success',data); // }, // error:function(data){ // console.log('error',data); // } // }) // function ajax(opt) { // opt = opt || {}; // opt.url = opt.url || ''; // opt.data = opt.data || null; // opt.success = opt.success || function () {}; // opt.method = (function (method) { // if (method) { // return method.toUpperCase() == 'GET' ? 'GET' : 'POST'; // }; // return 'GET'; // }(opt.method)); // opt.async = (function (async) { // return (!async ||async +'' == 'false') ? false : true; // }(opt.async)); // var xmlHttp = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); // var postData = (function (data) { // var params = []; // for (var key in data) { // params.push(key + '=' + data[key]); // } // return params.join('&'); // }(opt.data)); // if (opt.method === 'POST') { // xmlHttp.open(opt.method, opt.url, opt.async); // xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8'); // xmlHttp.send(postData); // } else if (opt.method === 'GET') { // xmlHttp.open(opt.method, opt.url + '?t=' + Math.random() + '&' + postData, opt.async); // xmlHttp.send(null); // } // xmlHttp.onreadystatechange = function () { // if (xmlHttp.readyState == 4) { // if (xmlHttp.status == 200) { // opt.success(xmlHttp.responseText); // } else { // opt.error(xmlHttp.status); // } // } // }; // } </script> </body> </html>
node
npm install uuid ws --save
let ws = require('ws'); let uuid = require('uuid'); let socketServer = ws.Server; let wss = new socketServer({port: 8090}); let clients = []; let clientIndex = 0; function broadcastSend(type, message, name) { clients.forEach(function(v, i) { if(v.ws.readyState === ws.OPEN) { v.ws.send(JSON.stringify({ "type": type, "name": name, "message": message })); } }) } //监听连接 wss.on('connection', function(ws) { let client_uuid = uuid.v4(); let name = `AnonymousUser${clientIndex++}`; clients.push({ "id": client_uuid, "ws": ws, "name": name }); console.log(`client ${client_uuid} connected`); /** * 关闭服务,从客户端监听列表删除 */ function closeSocket() { for(let i = 0; i < clients.length; i++) { if(clients[i].id == client_uuid) { let disconnect_message = `${name} has disconnected`; broadcastSend("notification", disconnect_message, name); clients.splice(i, 1); } } } /*监听消息*/ ws.on('message', function(message) { if(message.indexOf('/nick') === 0) { let name_array = message.split(' '); if(name_array.length >= 2) { let old_name = name; name = name_array[1]; let name_message = `Client ${old_name} change to ${name}`; broadcastSend("nick_update", name_message, name); } } else { broadcastSend("message", message, name); } }); /*监听断开连接*/ ws.on('close', function() { closeSocket(); }) })