问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

怎么连接nodejs服务器

发布网友 发布时间:2022-04-25 12:02

我来回答

1个回答

热心网友 时间:2022-05-14 16:48

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

简单开始

1.安装node。/  

2.安装ws模块

ws:是nodejs的一个WebSocket库,可以用来创建服务。

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());
}

页面:

 View Code

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

模拟股票

上面的例子很简单,只是为了演示如何运用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按钮用来修改昵称。

View Code

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协议。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
vivo y18l 死机卡在开机界面 vivoy18l手机频繁黑屏死机怎么办? vivo y18l 死机了怎么办 vivoY18l黑屏死机解决办法 vivo y18l刷机很久都开不了机怎么? 湖北自考专升本会有学籍吗? 湖北自考专升本后可以考研吗 湖北自考申请毕业证的时间在什么时候 湖北自考专升本学历怎么查询 湖北自考专升本为什么没有学籍 which引导的非限制定语从句可以修饰一个名词吗? spring festival eve是什么意思 求魔兽冰封所有英雄从祭坛出来时说的第一句台词,谢谢。 my dream ___半命题英语演讲 my home isclose to the lake TheparKisclosemyschool什么意思? hishouseisclosetomyhouse是什么意思中文 kate&#39;shomeisclosetoherschool是什么意思 ...is close to... 中的close要复数形式吗?为什么 is close to的colse为什么不加ing 人通过吃饭获得能量 人是如何利用这些能量的 人为什么要每天吃饭? 晚上吃饭太晚的坏处 “用眼睛吃饭的国家”是指( )。 以前农村人都喜欢蹲在家门口吃饭,你知道为什么吗? 吃饭时的姿势十大禁忌 人饿了会吃饭,所有的动物都是要吃东西的吗? 借几十块吃饭可以吗好心人帮帮? 熊虎争抢食物谁赢?作为自然界最大强盗,棕熊敢找老虎蹭饭吃吗? QQ餐厅里有四个菜系,但主菜单只有三个位置.请问我非得四个菜系都学么... 谈谈农村生活和城市生活得看法?英语作文带汉语不少于200字 whosehouseisclosetotheQUeenhouse怎么翻译? 黑豹乐队 张淇在我为歌狂唱过歌的英文歌叫什么 魔兽争霸3所有英雄说话的中文翻译 黄精 乌梅 玉竹 白果制成的催奶茶 喝了对宝宝有无负作用 乌梅黄精泡水的作用 玛咖,锁阳,韭菜子,黄精,乌梅这五味能混一起泡酒喝吗,有什么功效,适合什 ... 请问:锁阳 黄芪 黄精 乌梅能在一起泡酒吗?有什么效果? 黄精乌梅代用茶是泡着喝水还是和那些渣一起喝掉? 吃降糖药成份:葛根,玉竹,山药,枸杞子,乌梅,黄精,白芷影响要孩子吗? 黄精性温还是性凉,有啥用,和什么食物中和 北京同仁堂 黄精蜜膏100克蜂产品膏方蜂蜜黄精乌梅人参茯苓玉竹管什么... 黑枣乌梅何首黄精一起泡酒能起到什么功效 黄精,乌梅,玉竹,桔梗,甘草,蔗糖,糊精混合一起啥效果? 乌梅,防风,甘草,桔更,黄精起泡水喝能起什么作用会起副作用吗?能... 手机打电话的时候没有声音,几秒后就自动挂断是什么原因? 家里监控的软件却载了怎么下? 浴霸的LED灯不停的闪烁是什么原因? 浴霸灯老是闪是什么原因 浴霸灯总闪是什么原因