1、js高级程序设计
Web Sockets的目标是在一个单独的持久连接上提供全双工、双向通信。
在JavaScript中创建了Web Socket之后,会有一个HTTP请求发送到浏览器以发起连接。在取得服务器的响应后,建立的连接会使用HTTP升级从HTTP协议交换为Web Socket协议。
也就是说,使用标准的HTTP服务器无法实现Web Socket,只有支持这种协议的专门服务器才能正常工作。
注意:
1、Web Socket使用自定义的协议,http:// —— >ws ://;https://——>wss://;
2、使用Web Socket
1、要创建Web Socket,首先要实例一个WebSocket对象并传入要连接的URL: var socket = new WebSocket("ws://www.example.com/server.php"); 注意:同源策略对Web Sockets不适用,因此可以通过它打开到任何站点的连接,是否通信取决于服务器。 创建对象之后,浏览器会尝试创建连接,与XHR累死,WebSocket也有一个表示当前状态的readyState属性。 如下状态: WebSocket.OPENING(0) : 正在建立连接。 WebSocket.OPENING(1) : 已经建立连接。 WebSocket.CLOSING(2) : 正在关闭连接。 WebSocket.CLOSING(3) : 已经关闭连接。 WebSocket没有readyStatechange事件。 可以使用close()方法来关闭连接。 socket.close(); 2、发送和接收数据 使用***send();***来发送数据。 socket.send("Hello world!"); 因为WebSockets只能通过连接发送***连续***的纯文本数据,所以对于复杂的数据结构,发送之前要进行序列化。 如下序列化为JSON字符串,再发送到数据库。 var message = { time:new Date(), text:"Hello world", clientId:"sdfdsfsdfdf" }; socket.send(JSON.stringify(message)); 服务器接收到发送来的数据之后,接着WebSocket对象就会触发 message 事件。 然后把数据保存在event.data属性中,发送给浏览器端。 浏览器端接收到服务器发来的数据,需要先解析发来的字符串。 socket.onmessage = function(event){ var data = event.data ; //处理数据 } 3、其他事件 WebSocket 还有其他三个事件,在连接的生命周期的不同阶段触发。 open:成功建立连接时触发。 error:发生错误时触发,连接不能持续。 close:连接关闭时触发。 socket.onopen = function(){}; socket.onerror = function(){}; socket.onclose = function(){}; 不支持Dom2级事件侦听器,因此只能使用Dom0级的语法定义每个事件处理程序。 这三个事件有三个额外的属性: wasClean:布尔值,表示连接是否已关闭, code:服务器返回的数值状态码, reason:字符串,包含服务器发回的消息。 socket.onclose = function(event){ console.log("Was clean?" + event.waxClean + " Code=" + event.code + " Reason=" + event.reason); };
2、javascript权威指南
基本内容跟之前的讲解一样,客户端与服务端消息的发送都是: socket.send();
接收都是绑定到事件onmessage上:socket.onmessage = function(e){var message = e.data;//message就是接受到的数据}
介绍了一个实例如下:
wschatserver.js:服务代码
/* * This is server-side JavaScript, intended to be run with NodeJS. * It runs a WebSocket server on top of an HTTP server, using an external * websocket library from https://github.com/miksago/node-websocket-server/ * If it gets an HTTP request for "/" it returns the chat client HTML file. * Any other HTTP requests return 404. Messages received via the * WebSocket protocol are simply broadcast to all active connections. */ var http = require('http'); // Use Node's HTTP server API var ws = require('node-websocket-server'); // Use an external WebSocket library // Read the source of the chat client at startup. Used below. var clientui = require('fs').readFileSync("wschatclient.html"); // Create an HTTP server var httpserver = new http.Server(); // When the HTTP server gets a new request, run this function httpserver.on("request", function (request, response) { // If the request was for "/", send the client-side chat UI. if (request.url === "/") { // A request for the chat UI response.writeHead(200, {"Content-Type": "text/html"}); response.write(clientui); response.end(); } else { // Send a 404 "Not Found" code for any other request response.writeHead(404); response.end(); } }); // Now wrap a WebSocket server around the HTTP server var wsserver = ws.createServer({server: httpserver}); // Call this function when we receive a new connection request wsserver.on("connection", function(socket) { socket.send("Welcome to the chat room."); // Greet the new client socket.on("message", function(msg) { // Listen for msgs from the client console.log(msg); wsserver.broadcast(msg); // And broadcast them to everyone }); }); // Run the server on port 8000. Starting the WebSocket server starts the // HTTP server as well. Connect to http://localhost:8000/ to use it. wsserver.listen(7000);
wschatclient.html 浏览器呈现页面
<script> window.onload = function() { // Take care of some UI details var nick = prompt("Enter your nickname"); // Get user's nickname var input = document.getElementById("input"); // Find the input field input.focus(); // Set keyboard focus // Open a WebSocket to send and receive chat messages on. // Assume that the HTTP server we were downloaded from also functions as // a websocket server, and use the same host name and port, but change // from the http:// protocol to ws:// var socket = new WebSocket("ws://" + location.host + "/"); // This is how we receive messages from the server through the web socket socket.onmessage = function(event) { // When a new message arrives var msg = event.data; // Get text from event object var node = document.createTextNode(msg); // Make it into a text node var div = document.createElement("div"); // Create a <div> div.appendChild(node); // Add text node to div document.body.insertBefore(div, input); // And add div before input input.scrollIntoView(); // Ensure input elt is visible } // This is how we send messages to the server through the web socket input.onchange = function() { // When user strikes return var msg = nick + ": " + input.value; // Username plus user's input socket.send(msg); // Send it through the socket input.value = ""; // Get ready for more input } }; </script> <!-- The chat UI is just a single, wide text input field --> <!-- New chat messages will be inserted before this element --> <input id="input" style="width:100%"/>
安装node-websocket-server模块,原来的写的是websocket-server模块,但是有问题,换成这个模块之后,页面可以加载出来,但是好像不能发送消息,以后有时间了再看看,这原生的实现。
目前不能实现传递,不太明白什么原因。应该是这个模块使用方法不对。
3、网上的成功实例
以下实例使用socket.io可以实现多个页面与服务端的通信
app.js
//app.js var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); var path = require('path'); app.get('/', function(req, res){ res.sendFile(path.join(__dirname, 'index.html')); }); io.on('connection', function(socket){ console.log('a user connected'); socket.on('disconnect', function(){ console.log('user disconnected'); }); socket.on('chat messages', function(msg){ console.log('message: ' + msg); io.emit('chat messages', msg); }); }); app.set('port', process.env.PORT || 3000); var server = http.listen(app.get('port'), function() { console.log('start at port:' + server.address().port); });
index.html
<!doctype html> <html> <head> <meta charset = "utf-8"> <title>Socket.IO chat</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font: 13px Helvetica, Arial; } form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; } form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; } form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } #messages { list-style-type: none; margin: 0; padding: 0; } #messages li { padding: 5px 10px; } #messages li:nth-child(odd) { background: #eee; } </style> </head> <body> <ul id="messages"></ul> <form action=""> <input id="m" autocomplete="off" /><button>Send</button> </form> <script src="/socket.io/socket.io.js"></script> <script src="http://code.jquery.com/jquery-1.11.1.js"></script> <script> var socket = io(); $('form').submit(function(){ socket.emit('chat messages', $('#m').val()); $('#m').val(''); return false; }); socket.on('chat messages', function(msg){ $('#messages').append($('<li>').text(msg)); }); </script> </body> </html>
使用需要安装模块: socket.io express