最简单的socket服务端

  1. var net = require("net");
  2. server1 = net.createServer(function(client){
  3. client.write('Hello World!\r\n');
  4. });
  5.  
  6. server1.listen(9000);

websocket服务端的搭建

前面已经学习了WebSocket API,包括事件、方法和属性。详情:WebSocket(二)--API  WebSocket是基于事件驱动,支持全双工通信。下面通过三个简单例子体验一下。

简单开始

1.安装node。https://nodejs.org/en/

2.安装ws模块

ws:是nodejs的一个WebSocket库,可以用来创建服务。 https://github.com/websockets/ws

3.server.js

在项目里面新建一个server.js,创建服务,指定8181端口,将收到的消息log出来。

  1. var WebSocketServer = require('ws').Server,
  2. wss = new WebSocketServer({ port: 8181 });
  3. wss.on('connection', function (ws) {
  4. console.log('client connected');
  5. ws.on('message', function (message) {
  6. console.log(message);
  7. });
  8. });

4.建立一个client.html。

在页面上建立一个WebSocket的连接。用send方法发送消息。

  1. var ws = new WebSocket("ws://localhost:8181");
  2. ws.onopen = function (e) {
  3. console.log('Connection to server opened');
  4. }
  5. function sendMessage() {
  6. ws.send($('#message').val());
  7. }

页面:

  1. <html xmlns="http://www.w3.org/1999/xhtml">
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  4. <title>WebSocket Echo Demo</title>
  5. <meta name="viewport" content="width=device-width, initial-scale=1"/>
  6. <link href="../bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet" />
  7. <script src="../js/jquery-1.12.3.min.js"></script>
  8. <script src="../js/jquery-1.12.3.min.js"></script>
  9. <script src="../bootstrap-3.3.5/js/bootstrap.min.js"></script>
  10. <script>
  11. var ws = new WebSocket("ws://localhost:8181");
  12. ws.onopen = function (e) {
  13. console.log('Connection to server opened');
  14. }
  15. function sendMessage() {
  16. ws.send($('#message').val());
  17. }
  18. </script>
  19. </head>
  20.  
  21. <body >
  22. <div class="vertical-center">
  23. <div class="container">
  24. <p>&nbsp;</p>
  25. <form role="form" id="chat_form" onsubmit="sendMessage(); return false;">
  26. <div class="form-group">
  27. <input class="form-control" type="text" name="message" id="message"
  28. placeholder="Type text to echo in here" value="" />
  29. </div>
  30. <button type="button" id="send" class="btn btn-primary"
  31. onclick="sendMessage();">
  32. Send!
  33. </button>
  34. </form>
  35. </div>
  36. </div>
  37. </body>
  38. </html>

运行之后如下,服务端即时获得客户端的消息。

模拟股票(实例)

上面的例子很简单,只是为了演示如何运用nodejs的ws创建一个WebSocket服务器。且可以接受客户端的消息。那么下面这个例子演示股票的实时更新。客服端只需要连接一次,服务器端会不断地发送新数据,客户端收数据后更新UI.页面如下,有五只股票,开始和停止按钮测试连接和关闭。

服务端:

1.模拟五只股票的涨跌。

  1. var stocks = {
  2. "AAPL": 95.0,
  3. "MSFT": 50.0,
  4. "AMZN": 300.0,
  5. "GOOG": 550.0,
  6. "YHOO": 35.0
  7. }
  8. function randomInterval(min, max) {
  9. return Math.floor(Math.random() * (max - min + 1) + min);
  10. }
  11. var stockUpdater;
  12. var randomStockUpdater = function() {
  13. for (var symbol in stocks) {
  14. if(stocks.hasOwnProperty(symbol)) {
  15. var randomizedChange = randomInterval(-150, 150);
  16. var floatChange = randomizedChange / 100;
  17. stocks[symbol] += floatChange;
  18. }
  19. }
  20. var randomMSTime = randomInterval(500, 2500);
  21. stockUpdater = setTimeout(function() {
  22. randomStockUpdater();
  23. }, randomMSTime);
  24. }
  25. randomStockUpdater();

2.连接建立之后就开始更新数据

  1. wss.on('connection', function (ws) {
  2. var sendStockUpdates = function (ws) {
  3. if (ws.readyState == 1) {
  4. var stocksObj = {};
  5. for (var i = 0; i < clientStocks.length; i++) {
  6. var symbol = clientStocks[i];
  7. stocksObj[symbol] = stocks[symbol];
  8. }
  9. if (stocksObj.length !== 0) {
  10. ws.send(JSON.stringify(stocksObj));//需要将对象转成字符串。WebSocket只支持文本和二进制数据
  11. console.log("更新", JSON.stringify(stocksObj));
  12. }
  13.  
  14. }
  15. }
  16. var clientStockUpdater = setInterval(function () {
  17. sendStockUpdates(ws);
  18. }, 1000);
  19. ws.on('message', function (message) {
  20. var stockRequest = JSON.parse(message);//根据请求过来的数据来更新。
  21. console.log("收到消息", stockRequest);
  22. clientStocks = stockRequest['stocks'];
  23. sendStockUpdates(ws);
  24. });

客户端:

建立连接:

  1. var ws = new WebSocket("ws://localhost:8181");

onopen直接只有在连接成功后才会触发,在这个时候将客户端需要请求的股票发送给服务端。

  1. var isClose = false;
  2. var stocks = {
  3. "AAPL": 0, "MSFT": 0, "AMZN": 0, "GOOG": 0, "YHOO": 0
  4. };
  5. function updataUI() {
  6. ws.onopen = function (e) {
  7. console.log('Connection to server opened');
  8. isClose = false;
  9. ws.send(JSON.stringify(stock_request));
  10. console.log("sened a mesg");
  11. }
  12. //更新UI
  13. var changeStockEntry = function (symbol, originalValue, newValue) {
  14. var valElem = $('#' + symbol + ' span');
  15. valElem.html(newValue.toFixed(2));
  16. if (newValue < originalValue) {
  17. valElem.addClass('label-danger');
  18. valElem.removeClass('label-success');
  19. } else if (newValue > originalValue) {
  20. valElem.addClass('label-success');
  21. valElem.removeClass('label-danger');
  22. }
  23. }
  24. // 处理受到的消息
  25. ws.onmessage = function (e) {
  26. var stocksData = JSON.parse(e.data);
  27. console.log(stocksData);
  28. for (var symbol in stocksData) {
  29. if (stocksData.hasOwnProperty(symbol)) {
  30. changeStockEntry(symbol, stocks[symbol], stocksData[symbol]);
  31. stocks[symbol] = stocksData[symbol];
  32. }
  33. }
  34. };
  35. }
  36.  
  37. updataUI();

运行效果如下:只需要请求一次,数据就会不断的更新,效果是不是很赞,不用轮询,也不用长连接那么麻烦了。文章末尾会附上所有源码。

(美股的涨跌和A股的颜色是反的,即红跌绿涨)

实时聊天

上面的例子是连接建立之后,服务端不断给客户端发送数据。接下来例子是一个简单的聊天室类的例子。可以建立多个连接。

1.安装node-uuid模块,用来给每个连接一个唯一号。

2.服务端消息发送

消息类型分notification和message两种,前者是提示信息,后者是聊天内容。消息还包含一个id、昵称和消息内容。在上一节有学习到readyState有四个值,OPEN表示连接建立可以发送消息。如果页面关闭了,为WebSocket.CLOSE。

  1. function wsSend(type, client_uuid, nickname, message) {
  2. for (var i = 0; i < clients.length; i++) {
  3. var clientSocket = clients[i].ws;
  4. if (clientSocket.readyState === WebSocket.OPEN) {
  5. clientSocket.send(JSON.stringify({
  6. "type": type,
  7. "id": client_uuid,
  8. "nickname": nickname,
  9. "message": message
  10. }));
  11. }
  12. }
  13. }

3.服务端处理连接

每新增加一个连接,都会发送一条匿名用户的加入的提示消息,如果消息中带有“/nick” 认为这一个修改昵称的消息。然后更新客户端的昵称。其他都会当做聊天消息处理。

  1. wss.on('connection', function(ws) {
  2. var client_uuid = uuid.v4();
  3. var nickname = "AnonymousUser" + clientIndex;
  4. clientIndex += 1;
  5. clients.push({ "id": client_uuid, "ws": ws, "nickname": nickname });
  6. console.log('client [%s] connected', client_uuid);
  7. var connect_message = nickname + " has connected";
  8. wsSend("notification", client_uuid, nickname, connect_message);
  9. console.log('client [%s] connected', client_uuid);
  10. ws.on('message', function(message) {
  11. if (message.indexOf('/nick') === 0) {
  12. var nickname_array = message.split(' ');
  13. if (nickname_array.length >= 2) {
  14. var old_nickname = nickname;
  15. nickname = nickname_array[1];
  16. var nickname_message = "Client " + old_nickname + " changed to " + nickname;
  17. wsSend("nick_update", client_uuid, nickname, nickname_message);
  18. }
  19. } else {
  20. wsSend("message", client_uuid, nickname, message);
  21. }
  22. });

处理连接关闭:

  1. var closeSocket = function(customMessage) {
  2. for (var i = 0; i < clients.length; i++) {
  3. if (clients[i].id == client_uuid) {
  4. var disconnect_message;
  5. if (customMessage) {
  6. disconnect_message = customMessage;
  7. } else {
  8. disconnect_message = nickname + " has disconnected";
  9. }
  10. wsSend("notification", client_uuid, nickname, disconnect_message);
  11. clients.splice(i, 1);
  12. }
  13. }
  14. };
  15. ws.on('close', function () {
  16. closeSocket();
  17. });

4.客户端

没有启动时,页面如下,change按钮用来修改昵称。

  1. <div class="vertical-center">
  2. <div class="container">
  3. <ul id="messages" class="list-unstyled"></ul>
  4. <hr/>
  5. <form role="form" id="chat_form" onsubmit="sendMessage(); return false;">
  6. <div class="form-group">
  7. <input class="form-control" type="text" id="message" name="message"
  8. placeholder="Type text to echo in here" value="" autofocus/>
  9. </div>
  10. <button type="button" id="send" class="btn btn-primary"
  11. onclick="sendMessage();">
  12. Send Message
  13. </button>
  14.  
  15. </form>
  16. <div class="form-group"><span>nikename:</span><input id="name" type="text" /> <button class="btn btn-sm btn-info" onclick="changName();">change</button></div>
  17. </div>
  18. </div>

js:

  1. //建立连接
  2. var ws = new WebSocket("ws://localhost:8181");
  3. var nickname = "";
  4. ws.onopen = function (e) {
  5. console.log('Connection to server opened');
  6. }
  7. //显示
  8. function appendLog(type, nickname, message) {
  9. if (typeof message == "undefined") return;
  10. var messages = document.getElementById('messages');
  11. var messageElem = document.createElement("li");
  12. var preface_label;
  13. if (type === 'notification') {
  14. preface_label = "<span class=\"label label-info\">*</span>";
  15. } else if (type == 'nick_update') {
  16. preface_label = "<span class=\"label label-warning\">*</span>";
  17. } else {
  18. preface_label = "<span class=\"label label-success\">"
  19. + nickname + "</span>";
  20. }
  21. var message_text = "<h2>" + preface_label + "&nbsp;&nbsp;"
  22. + message + "</h2>";
  23. messageElem.innerHTML = message_text;
  24. messages.appendChild(messageElem);
  25. }
  26. //收到消息处理
  27. ws.onmessage = function (e) {
  28. var data = JSON.parse(e.data);
  29. nickname = data.nickname;
  30. appendLog(data.type, data.nickname, data.message);
  31. console.log("ID: [%s] = %s", data.id, data.message);
  32. }
  33. ws.onclose = function (e) {
  34. appendLog("Connection closed");
  35. console.log("Connection closed");
  36. }
  37. //发送消息
  38. function sendMessage() {
  39. var messageField = document.getElementById('message');
  40. if (ws.readyState === WebSocket.OPEN) {
  41. ws.send(messageField.value);
  42. }
  43. messageField.value = '';
  44. messageField.focus();
  45. }
  46. //修改名称
  47. function changName() {
  48. var name = $("#name").val();
  49. if (ws.readyState === WebSocket.OPEN) {
  50. ws.send("/nick " + name);
  51. }
  52. }

运行结果:

页面关闭之后,连接马上断开。

这种实时响应的体验简直不能太爽,代码也清爽了,前端体验也更好,客户端不用一直发请求,服务端不用等着被轮询。

小结:上面例子的代码都很好理解,接下来学习WebSocket协议。

源码:http://pan.baidu.com/s/1c2FfKbA

源码:http://pan.baidu.com/s/1o8KRmUQ  加入了socket.io的实现。

API:WebSocket API

相关:websoket使用Protocol Buffers3.0传输

转 :https://www.cnblogs.com/stoneniqiu/p/5402311.html

WebSocket 学习--用nodejs搭建服务器的更多相关文章

  1. nodejs搭建服务器 和 操作数据库

    1.express框架:是一个简洁而灵活的 node.js Web应用框架.一般的项目都是基于这个框架开发的.http://www.runoob.com/nodejs/nodejs-express-f ...

  2. node学习笔记2——搭建服务器

    搭建服务器关键词: require('http') —— 请求 node 里面的 http 模块 createServer —— 创建一个服务器 request —— 请求 response—— 响应 ...

  3. WebSocket 学习(三)--用nodejs搭建服务器

    前面已经学习了WebSocket API,包括事件.方法和属性.详情:WebSocket(二)--API  WebSocket是基于事件驱动,支持全双工通信.下面通过三个简单例子体验一下. 简单开始 ...

  4. 利用nodejs搭建服务器,测试AJAX

    最近学习了AJAX一直没有进行过测试,前今天了解了Noejs搭建本地服务器下就尝试了一下.通过AJAX请求的方式获取HTTP服务器返回数据的代码 首先创建一个serve.js的文件.并写入以下代码. ...

  5. 使用nodejs搭建服务器显示HTML页面

    首先安装express 在命令行输入:npm install express -g 安装完成后可以查看安装情况:npm ls -g 然后创建server.js文件 var express = requ ...

  6. 用nodejs搭建类似于C++的服务器后台.类似网易pomelo

    实际的情况,用nodejs跑业务,非常的快,只要用好其无阻塞和回调这两点,处理速度真的是杠杠的. 从年初开始,我用nodejs搭建了类似C++的服务器后台,也想和做同样的事情的朋友分享,本服务平台因为 ...

  7. NodeJs本地搭建服务器,模拟接口请求,获取json数据

    最近在学习Node.js,虽然就感觉学了点皮毛,感觉这个语言还不错,并且也会一步步慢慢的学着的,这里实现下NodeJs本地搭建服务器,模拟接口请求,获取json数据. 具体的使用我就不写了,这个博客写 ...

  8. NodeJS搭建HTTPS服务器

    [NodeJS搭建HTTPS服务器] http://cnodejs.org/topic/54745ac22804a0997d38b32d

  9. 用nodejs搭建一个简单的服务器

    使用nodejs搭建一个简单的服务器 nodejs优点:性能高(读写文件) 数据操作能力强 官网:www.nodejs.org 验证是否安装成功:cmd命令行中输入node -v 如果显示版本号表示安 ...

随机推荐

  1. Android 开源项目android-open-project解析之(四) ColorPickView,GraphView,UI Style,Other

    十三.ColorPickView ColorPickerView 颜色选择器,支持PopupWindows或新的Activity中打开 项目地址:https://code.google.com/p/c ...

  2. osgi实战学习之路:2. maven+maven-bundle-plugin+karaf搭建osgi之HelloWorld

    环境准备: jdk版本号 jdk:1.7 karaf: 版本号:apache-karaf-3.0.1 下载地址: http://pan.baidu.com/s/1qWM4Y1u http://kara ...

  3. Unity3D协程介绍 以及 使用

    作者ChevyRay ,2013年9月28日,snaker7译  原文地址:http://unitypatterns.com/introduction-to-coroutines/ 在Unity中,协 ...

  4. IDE的文件和代码模板

    设置IDE的的模板,可以在创建文件的时候,自动产生模板内容,模板里可以 模板头设置: # -*- coding: utf- -*- """ --------------- ...

  5. HTML:图片和视频标签的使用

    介绍:在html网页中,图片和视频是基本的元素,在网页中插入图片和视频有自己的标签,分别是img.embed,来源都是使用src来链接. 插入图片: <img src="图片的来源&q ...

  6. Android4.2.2 Gallery2源码分析(5)——GLCanvasImpl.java

    GLCanvasImpl.java是接口GLCanvas的唯一实现类,也就是说二者在功能上完全等同.代码中调用GLCanvas对象函数的地方,等效于调用GLCanvasImpl中的该函数,GLCanv ...

  7. 解决Windows server 2012 R2 系统使用IIS8浏览Asp程序出现"An error occurred on the server when processing the URL"错误

    进入IIS并将ASP里的“Send Error To Browser”设置为True后点击Appley保存即可 原因是IIS里的Asp设置禁用上当错误信息发送给浏览器,只要启用即可 如果没有Asp选项 ...

  8. scala lambda 小括号与大括号

    看akka源码的时候看到这样的一个用法: 作为接触scala两天半的我有些看不明白了.好一番搜索看到这样的答案: <scala雾中风景(2): 小括号与花括号> 下面的问题,表面上看是小括 ...

  9. (剑指Offer)面试题42:翻转单词顺序

    题目: 输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理. 例如输入字符串“I am a student.”,则输出"student. ...

  10. C#应用视频教程1.2 Socket通信客户端实现

    接下来我们尝试实现最简单的Socket客户端,为了确保只可能你的代码有问题,服务器要先用别人成熟的代码测试(这也是编程的一个技巧,先不要用自己写的客户端测试自己写的服务器,这样出了问题你也不知道谁有问 ...