项目目录
├── package-lock.json
├── package.json
├── public
│ └── index.html
└── server
└── server.js
初始化
npm init
npm install --save express
index.html
1 |
|
server.js
1 | const path = require('path'); |
package.json
1 | { |
部署hekuro
1 | > heroku create |
使用socket.io
安装:
1 | npm install -save socket.io |
socket.io可以让服务器与客户端相互连接并触发事件。下例测试连接与断开服务器
server.html:
1 | const path = require('path'); |
index.html:
1 |
|
运行:打开localhost:3000即可运行,查看控制台输出的语句。
1 | > node server/server.js |
##项目目录重构
创建和触发自定义事件。
将客户端js代码分离出来:
|—— node_moudles
├── package-lock.json
├── package.json
├── public
│ ├── index.html
│ └── js
│ └── index.js
└── server
└── server.js
index.html:
1 |
|
index.js:
为了让浏览器识别,将匿名函数修改为function
1 | var socket = io(); |
server.js:
1 | const path = require('path'); |
运行:打开localhost:3000即可运行,查看控制台输出的语句。
1 | > node server/server.js |
广播
当客户端连接服务器之后,所有的节点即会触发newMessage事件,但是当前连接的客户端与其他客户端接受的信息不相同。
当前客户端接受:Welcome to the chat app
其他客户端接受:New user joined
index.html:
1 |
|
index.js:
为了让浏览器识别,将匿名函数修改为function
1 | var socket = io(); |
server.js:
1 | const path = require('path'); |
测试
运行:
1 | > node server/server.js |
分别打开两个浏览器tabs,
打开localhost:3000查看控制台输出的语句。
封装产生信息
目录
├── package-lock.json
├── package.json
├── public
│ ├── index.html
│ └── js
│ └── index.js
└── server
├── server.js
└── utils
└── message.js
index.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>Welcome to the chat app</p>
<script src="/socket.io/socket.io.js"></script>
<script src="/js/index.js"></script>
</body>
</html>
index.js:
为了让浏览器识别,将匿名函数修改为function
1
2
3
4
5
6
7
8
9
10
11
12
13
var socket = io();
socket.on('connect', function () {
console.log('Connected to server');
});
socket.on('disconnect', function () {
console.log('Disconnected from server');
});
socket.on('newMessage', function (message) {
console.log('newMessage', message);
});
message.js
1 | var generateMessage = (from, text) => { |
server.js
1 | const path = require('path'); |
测试
运行:
1 | > node server/server.js |
分别打开两个浏览器tabs,
打开localhost:3000查看控制台输出的语句。
信息反馈
当客户端发出一条消息,希望得到服务器的反馈,如果服务器发送成功个,会收到消息。
index.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>Welcome to the chat app</p>
<script src="/socket.io/socket.io.js"></script>
<script src="/js/index.js"></script>
</body>
</html>
index.js:
为了让浏览器识别,将匿名函数修改为function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var socket = io();
socket.on('connect', function () {
console.log('Connected to server');
});
socket.on('disconnect', function () {
console.log('Disconnected from server');
});
socket.on('newMessage', function (message) {
console.log('newMessage', message);
});
socket.emit('createMessage', {
from: 'Frank',
text: 'Hi'
}, function (data) {//回调函数
console.log('Got it', data);
});
message.js
1 | var generateMessage = (from, text) => { |
server.js
1 | const path = require('path'); |
测试
运行:
1 | > node server/server.js |
分别打开两个浏览器tabs,
打开localhost:3000查看控制台输出的语句。
## 简单聊天页面
index.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>Welcome to the chat app</p>
<script src="/socket.io/socket.io.js"></script>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<ol id="messages"></ol>
<form id="message-form">
<input name="message" type="text" placeholder="Message"/>
<button>Send</button>
</form>
<script src="/js/index.js"></script>
</body>
</html>
index.js:
为了让浏览器识别,将匿名函数修改为function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var socket = io();
socket.on('connect', function () {
console.log('Connected to server');
});
socket.on('disconnect', function () {
console.log('Disconnected from server');
});
//新消息来了之后,添加到页面中
socket.on('newMessage', function (message) {
console.log('newMessage', message);
var li = jQuery('<li></li>');
li.text(`${message.from}: ${message.text}`);
jQuery('#messages').append(li);
});
//按钮提交事件
jQuery('#message-form').on('submit', function (e) {
e.preventDefault();
socket.emit('createMessage', {
from: 'User',
text: jQuery('[name=message]').val()
}, function () {
});
});
message.js
1 | var generateMessage = (from, text) => { |
server.js
1 | const path = require('path'); |
测试
运行:
1 | > node server/server.js |
分别打开两个浏览器tabs,
打开localhost:3000查看控制台输出的语句。
经纬度
index.js
1 | var socket = io(); |
index.html
1 |
|
message.js
1 | var generateMessage = (from, text) => { |
server.js
1 | const path = require('path'); |
谷歌经纬度
index.js
1 | var socket = io(); |
index.html
1 |
|
message.js
1 | var generateMessage = (from, text) => { |
server.js
1 | const path = require('path'); |
页面优化
css/style.css:
1 | button,button:hover{border:none;color:#fff;padding:10px}.chat__messages,.chat__sidebar ul{list-style-type:none}*{box-sizing:border-box;margin:0;padding:0;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;font-weight:300;font-size:.95rem}li,ul{list-style-position:inside}h3{font-weight:600;text-align:center;font-size:1.5rem}button{background:#265f82;cursor:pointer;transition:background .3s ease}button:hover{background:#1F4C69}button:disabled{cursor:default;background:#698ea5}.centered-form{display:flex;align-items:center;height:100vh;width:100vw;justify-content:center;background:-moz-linear-gradient(125deg,rgba(39,107,130,1) 0,rgba(49,84,129,1) 100%);background:-webkit-gradient(linear,left top,right bottom,color-stop(0,rgba(49,84,129,1)),color-stop(100%,rgba(39,107,130,1)));background:-webkit-linear-gradient(125deg,rgba(39,107,130,1) 0,rgba(49,84,129,1) 100%);background:-o-linear-gradient(125deg,rgba(39,107,130,1) 0,rgba(49,84,129,1) 100%);background:-ms-linear-gradient(125deg,rgba(39,107,130,1) 0,rgba(49,84,129,1) 100%);background:linear-gradient(325deg,rgba(39,107,130,1) 0,rgba(49,84,129,1) 100%)}.centered-form__form{background:rgba(250,250,250,.9);border:1px solid #e1e1e1;border-radius:5px;padding:0 20px;margin:20px;width:230px}.form-field{margin:20px 0}.form-field>*{width:100%}.form-field label{display:block;margin-bottom:7px}.form-field input,.form-field select{border:1px solid #e1e1e1;padding:10px}.chat{display:flex}.chat__sidebar{overflow-y:scroll;width:260px;height:100vh;background:-moz-linear-gradient(125deg,rgba(39,107,130,1) 0,rgba(49,84,129,1) 100%);background:-webkit-gradient(linear,left top,right bottom,color-stop(0,rgba(49,84,129,1)),color-stop(100%,rgba(39,107,130,1)));background:-webkit-linear-gradient(125deg,rgba(39,107,130,1) 0,rgba(49,84,129,1) 100%);background:-o-linear-gradient(125deg,rgba(39,107,130,1) 0,rgba(49,84,129,1) 100%);background:-ms-linear-gradient(125deg,rgba(39,107,130,1) 0,rgba(49,84,129,1) 100%);background:linear-gradient(325deg,rgba(39,107,130,1) 0,rgba(49,84,129,1) 100%)}.chat__footer,.chat__sidebar li{background:#e6eaee;padding:10px}.chat__sidebar h3{color:#e6eaee;margin:10px 20px;text-align:left}.chat__sidebar li{border:1px solid #e1e1e1;border-radius:5px;margin:10px}.chat__main{display:flex;flex-direction:column;height:100vh;width:100%}.chat__messages{flex-grow:1;overflow-y:scroll;-webkit-overflow-scrolling:touch;padding:10px}.chat__footer{display:flex;flex-shrink:0}.chat__footer form{flex-grow:1;display:flex}.chat__footer form *{margin-right:10px}.chat__footer input{border:none;padding:10px;flex-grow:1}.message{padding:10px}.message__title{display:flex;margin-bottom:5px}.message__title h4{font-weight:600;margin-right:10px}.message__title span{color:#999}@media (max-width:600px){*{font-size:1rem}.chat__sidebar{display:none}.chat__footer{flex-direction:column}.chat__footer form{margin-bottom:10px}.chat__footer button{margin-right:0}} |
index.js
1 | var socket = io(); |