最简单的socket服务端

var net = require("net");
server1 = net.createServer(function(client){
client.write('Hello World!\r\n');
}); 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出来。

var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({ port: 8181 });
wss.on('connection', function (ws) {
console.log('client connected');
ws.on('message', function (message) {
console.log(message);
});
});

4.建立一个client.html。

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

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

页面:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>WebSocket Echo Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link href="../bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="../js/jquery-1.12.3.min.js"></script>
<script src="../js/jquery-1.12.3.min.js"></script>
<script src="../bootstrap-3.3.5/js/bootstrap.min.js"></script>
<script>
var ws = new WebSocket("ws://localhost:8181");
ws.onopen = function (e) {
console.log('Connection to server opened');
}
function sendMessage() {
ws.send($('#message').val());
}
</script>
</head> <body >
<div class="vertical-center">
<div class="container">
<p>&nbsp;</p>
<form role="form" id="chat_form" onsubmit="sendMessage(); return false;">
<div class="form-group">
<input class="form-control" type="text" name="message" id="message"
placeholder="Type text to echo in here" value="" />
</div>
<button type="button" id="send" class="btn btn-primary"
onclick="sendMessage();">
Send!
</button>
</form>
</div>
</div>
</body>
</html>

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

模拟股票(实例)

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

服务端:

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

var stocks = {
"AAPL": 95.0,
"MSFT": 50.0,
"AMZN": 300.0,
"GOOG": 550.0,
"YHOO": 35.0
}
function randomInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
var stockUpdater;
var randomStockUpdater = function() {
for (var symbol in stocks) {
if(stocks.hasOwnProperty(symbol)) {
var randomizedChange = randomInterval(-150, 150);
var floatChange = randomizedChange / 100;
stocks[symbol] += floatChange;
}
}
var randomMSTime = randomInterval(500, 2500);
stockUpdater = setTimeout(function() {
randomStockUpdater();
}, randomMSTime);
}
randomStockUpdater();

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

wss.on('connection', function (ws) {
var sendStockUpdates = function (ws) {
if (ws.readyState == 1) {
var stocksObj = {};
for (var i = 0; i < clientStocks.length; i++) {
var symbol = clientStocks[i];
stocksObj[symbol] = stocks[symbol];
}
if (stocksObj.length !== 0) {
ws.send(JSON.stringify(stocksObj));//需要将对象转成字符串。WebSocket只支持文本和二进制数据
console.log("更新", JSON.stringify(stocksObj));
} }
}
var clientStockUpdater = setInterval(function () {
sendStockUpdates(ws);
}, 1000);
ws.on('message', function (message) {
var stockRequest = JSON.parse(message);//根据请求过来的数据来更新。
console.log("收到消息", stockRequest);
clientStocks = stockRequest['stocks'];
sendStockUpdates(ws);
});

客户端:

建立连接:

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

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

var isClose = false;
var stocks = {
"AAPL": 0, "MSFT": 0, "AMZN": 0, "GOOG": 0, "YHOO": 0
};
function updataUI() {
ws.onopen = function (e) {
console.log('Connection to server opened');
isClose = false;
ws.send(JSON.stringify(stock_request));
console.log("sened a mesg");
}
//更新UI
var changeStockEntry = function (symbol, originalValue, newValue) {
var valElem = $('#' + symbol + ' span');
valElem.html(newValue.toFixed(2));
if (newValue < originalValue) {
valElem.addClass('label-danger');
valElem.removeClass('label-success');
} else if (newValue > originalValue) {
valElem.addClass('label-success');
valElem.removeClass('label-danger');
}
}
// 处理受到的消息
ws.onmessage = function (e) {
var stocksData = JSON.parse(e.data);
console.log(stocksData);
for (var symbol in stocksData) {
if (stocksData.hasOwnProperty(symbol)) {
changeStockEntry(symbol, stocks[symbol], stocksData[symbol]);
stocks[symbol] = stocksData[symbol];
}
}
};
} updataUI();

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

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

实时聊天

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

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

2.服务端消息发送

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

function wsSend(type, client_uuid, nickname, message) {
for (var i = 0; i < clients.length; i++) {
var clientSocket = clients[i].ws;
if (clientSocket.readyState === WebSocket.OPEN) {
clientSocket.send(JSON.stringify({
"type": type,
"id": client_uuid,
"nickname": nickname,
"message": message
}));
}
}
}

3.服务端处理连接

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

wss.on('connection', function(ws) {
var client_uuid = uuid.v4();
var nickname = "AnonymousUser" + clientIndex;
clientIndex += 1;
clients.push({ "id": client_uuid, "ws": ws, "nickname": nickname });
console.log('client [%s] connected', client_uuid);
var connect_message = nickname + " has connected";
wsSend("notification", client_uuid, nickname, connect_message);
console.log('client [%s] connected', client_uuid);
ws.on('message', function(message) {
if (message.indexOf('/nick') === 0) {
var nickname_array = message.split(' ');
if (nickname_array.length >= 2) {
var old_nickname = nickname;
nickname = nickname_array[1];
var nickname_message = "Client " + old_nickname + " changed to " + nickname;
wsSend("nick_update", client_uuid, nickname, nickname_message);
}
} else {
wsSend("message", client_uuid, nickname, message);
}
});

处理连接关闭:

  var closeSocket = function(customMessage) {
for (var i = 0; i < clients.length; i++) {
if (clients[i].id == client_uuid) {
var disconnect_message;
if (customMessage) {
disconnect_message = customMessage;
} else {
disconnect_message = nickname + " has disconnected";
}
wsSend("notification", client_uuid, nickname, disconnect_message);
clients.splice(i, 1);
}
}
};
ws.on('close', function () {
closeSocket();
});

4.客户端

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

<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>

js:

   //建立连接
var ws = new WebSocket("ws://localhost:8181");
var nickname = "";
ws.onopen = function (e) {
console.log('Connection to server opened');
}
//显示
function appendLog(type, nickname, message) {
if (typeof message == "undefined") return;
var messages = document.getElementById('messages');
var messageElem = document.createElement("li");
var preface_label;
if (type === 'notification') {
preface_label = "<span class=\"label label-info\">*</span>";
} else if (type == 'nick_update') {
preface_label = "<span class=\"label label-warning\">*</span>";
} else {
preface_label = "<span class=\"label label-success\">"
+ nickname + "</span>";
}
var message_text = "<h2>" + preface_label + "&nbsp;&nbsp;"
+ message + "</h2>";
messageElem.innerHTML = message_text;
messages.appendChild(messageElem);
}
//收到消息处理
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 sendMessage() {
var messageField = document.getElementById('message');
if (ws.readyState === WebSocket.OPEN) {
ws.send(messageField.value);
}
messageField.value = '';
messageField.focus();
}
//修改名称
function changName() {
var name = $("#name").val();
if (ws.readyState === WebSocket.OPEN) {
ws.send("/nick " + name);
}
}

运行结果:

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

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

小结:上面例子的代码都很好理解,接下来学习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. SpringSecurity3整合CAS实现单点登录

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  2. Javascript:拦截所有AJAX调用,重点处理服务器异常

    背景 上篇文章http://www.cnblogs.com/happyframework/p/3241063.html介绍了如何以AOP的形式处理服务器异常,这让服务器端的编程逻辑变的非常整洁,本文介 ...

  3. 使用Jacob与Word文件交互

    转自:http://www.blogjava.net/lonsy/archive/2009/01/09/250713.html Jacob项目的官方地址: Http://sourceforge.net ...

  4. Android API 中文(14) —— ViewStub

    前言 关键字: android.view.ViewStub,版本为Android 2.2 r1 本章翻译来自唐明 ,这里本博负责整理和发布,欢迎其他译者一起参与Android API 的中文翻译行动, ...

  5. json-lib 的maven dependency

    项目中要用到json-lib,mvnrepository.com查找它的dependency时结果如下: <dependency> <groupId>net.sf.json-l ...

  6. Element 'beans' cannot have character [children]

    在编写spring的applicationContext.xml文件时,出现了: Element 'beans' cannot have character [children], because t ...

  7. 程序编译是出现"field has incomplete type"问题的解决

    在编译程序是出现了如下错误, 类或结构体的前向声明只能用来定义指针对象或引用,因为编译到这里时还没有发现定义,不知道该类或者结构的内部成员,没有办法具体的构造一个对象,所以会报错. 将类成员改成指针就 ...

  8. 服务器主机上RAID Card的Write Caching Policy

    在Cisco Server的DRAC中, 创建virtual drive时, 会看到下面的选项.   那么Write back, write through, write back bad BBU之间 ...

  9. 如何在SharePoint的列表中使用通配符来filter出ListItem?

    一个朋友问我这样一个问题, 他想要快速从SharePoint的文档库中filter出来名字中先带有一个Q, 接着一些其他的字符, 后面再跟着有一个数字20这样的文件.   第一个想法就是修改Share ...

  10. SQL OUTER JOIN

    When we want to select out all the record from two table, no matter it's present at second table or ...