内容简介:├── package-lock.json├── package.json├── public
项目目录
├── package-lock.json
├── package.json
├── public
│ └── index.html
└── server
└── server.js
初始化
npm init
npm install --save express
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <p>Welcome to the chat app</p> </body> </html>
server.js
const path = require('path');
const express = require('express');
//获取路劲,有讲究
const publicPath = path.join(__dirname, '../public');
const port = process.env.PORT || 3000;
var app = express();
app.use(express.static(publicPath));
app.listen(port, () => {
console.log(`Server is up on ${port}`);
});
package.json
{
"name": "node-chat-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
/* 启动脚本 */
"start": "node server/server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
/* node版本号 */
"engines": {
"node": "10.13.0"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.14.0"
}
}
部署hekuro
> heroku create > git push https://git.heroku.com/rocky-shore-24556.git
使用socket.io
安装:
npm install -save socket.io
socket.io可以让服务器与客户端相互连接并触发事件。下例测试连接与断开服务器
server.html:
const path = require('path');
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const publicPath = path.join(__dirname, '../public');
const port = process.env.PORT || 3000;
var app = express();
var server = http.createServer(app);
var io = socketIO(server);
app.use(express.static(publicPath));
io.on('connection', (socket) => {
console.log('New user connected');
socket.on('disconnect', () => {
console.log('User was disconnected');
});
});
server.listen(port, () => {
console.log(`Server is up on ${port}`);
});
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<p>Welcome to the chat app</p>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('connect', () => {
console.log('Connected to server');
});
socket.on('disconnect', () => {
console.log('Disconnected from server');
});
</script>
</body>
</html>
运行:打开localhost:3000即可运行,查看控制台输出的语句。
> node server/server.js
##项目目录重构
创建和触发自定义事件。
将客户端js代码分离出来:
|—— node_moudles
├── package-lock.json
├── package.json
├── public
│ ├── index.html
│ └── js
│ └── index.js
└── server
└── server.js
index.html:
<!DOCTYPE html> <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
var socket = io();
socket.on('connect', function () {
console.log('Connected to server');
socket.emit('createMessage', {
from: 'Andrew',
text: 'Yup, that works for me.'
});
});
socket.on('disconnect', function () {
console.log('Disconnected from server');
});
socket.on('newMessage', function (message) {
console.log('newMessage', message);
});
server.js:
const path = require('path');
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const publicPath = path.join(__dirname, '../public');
const port = process.env.PORT || 3000;
var app = express();
var server = http.createServer(app);
var io = socketIO(server);
app.use(express.static(publicPath));
io.on('connection', (socket) => {
console.log('New user connected');
socket.emit('newMessage', {
from: 'John',
text: 'See you then',
createdAt: 123123
});
socket.on('createMessage', (message) => {
console.log('createMessage', message);
});
socket.on('disconnect', () => {
console.log('User was disconnected');
});
});
server.listen(port, () => {
console.log(`Server is up on ${port}`);
});
运行:打开localhost:3000即可运行,查看控制台输出的语句。
> node server/server.js
广播
当客户端连接服务器之后,所有的节点即会触发newMessage事件,但是当前连接的客户端与其他客户端接受的信息不相同。
当前客户端接受:Welcome to the chat app
其他客户端接受:New user joined
index.html:
<!DOCTYPE html> <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
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);
});
server.js:
const path = require('path');
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const publicPath = path.join(__dirname, '../public');
const port = process.env.PORT || 3000;
var app = express();
var server = http.createServer(app);
var io = socketIO(server);
app.use(express.static(publicPath));
io.on('connection', (socket) => {
console.log('New user connected');
// 当客户端连接之后,即会触发newMessage事件,但是当前连接的客户端与其他客户端接受的信息不相同。
// 只发送给当前连接的节点
socket.emit('newMessage', {
from: 'Admin',
text: 'Welcome to the chat app',
createdAt: new Date().getTime()
});
// 只发送给当前连接的节点发送给其他节点
socket.broadcast.emit('newMessage', {
from: 'Admin',
text: 'New user joined',
createdAt: new Date().getTime()
});
socket.on('createMessage', (message) => {
console.log('createMessage', message);
io.emit('newMessage', {
from: message.from,
text: message.text,
createdAt: new Date().getTime()
});
// socket.broadcast.emit('newMessage', {
// from: message.from,
// text: message.text,
// createdAt: new Date().getTime()
// });
});
socket.on('disconnect', () => {
console.log('User was disconnected');
});
});
server.listen(port, () => {
console.log(`Server is up on ${port}`);
});
测试
运行:
> 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:
<!DOCTYPE html> <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
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
var generateMessage = (from, text) => {
return {
from,
text,
createdAt: new Date().getTime()
};
};
module.exports = {generateMessage};
server.js
const path = require('path');
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const {generateMessage} = require('./utils/message');
const publicPath = path.join(__dirname, '../public');
const port = process.env.PORT || 3000;
var app = express();
var server = http.createServer(app);
var io = socketIO(server);
app.use(express.static(publicPath));
io.on('connection', (socket) => {
console.log('New user connected');
socket.emit('newMessage', generateMessage('Admin', 'Welcome to the chat app'));
socket.broadcast.emit('newMessage', generateMessage('Admin', 'New user joined'));
socket.on('createMessage', (message) => {
console.log('createMessage', message);
io.emit('newMessage', generateMessage(message.from, message.text));
// socket.broadcast.emit('newMessage', {
// from: message.from,
// text: message.text,
// createdAt: new Date().getTime()
// });
});
socket.on('disconnect', () => {
console.log('User was disconnected');
});
});
server.listen(port, () => {
console.log(`Server is up on ${port}`);
});
测试
运行:
> node server/server.js
分别打开两个浏览器tabs,
打开localhost:3000查看控制台输出的语句。
信息反馈
当客户端发出一条消息,希望得到服务器的反馈,如果服务器发送成功个,会收到消息。
index.html:
<!DOCTYPE html> <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
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
var generateMessage = (from, text) => {
return {
from,
text,
createdAt: new Date().getTime()
};
};
module.exports = {generateMessage};
server.js
const path = require('path');
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const {generateMessage} = require('./utils/message');
const publicPath = path.join(__dirname, '../public');
const port = process.env.PORT || 3000;
var app = express();
var server = http.createServer(app);
var io = socketIO(server);
app.use(express.static(publicPath));
io.on('connection', (socket) => {
console.log('New user connected');
socket.emit('newMessage', generateMessage('Admin', 'Welcome to the chat app'));
socket.broadcast.emit('newMessage', generateMessage('Admin', 'New user joined'));
socket.on('createMessage', (message, callback) => {
console.log('createMessage', message);
io.emit('newMessage', generateMessage(message.from, message.text));
callback('This is from the server.'); //客户端执行回调函数
// socket.broadcast.emit('newMessage', {
// from: message.from,
// text: message.text,
// createdAt: new Date().getTime()
// });
});
socket.on('disconnect', () => {
console.log('User was disconnected');
});
});
server.listen(port, () => {
console.log(`Server is up on ${port}`);
});
测试
运行:
> node server/server.js
分别打开两个浏览器tabs,
打开localhost:3000查看控制台输出的语句。
## 简单聊天页面
index.html:
<!DOCTYPE html> <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
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
var generateMessage = (from, text) => {
return {
from,
text,
createdAt: new Date().getTime()
};
};
module.exports = {generateMessage};
server.js
const path = require('path');
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const {generateMessage} = require('./utils/message');
const publicPath = path.join(__dirname, '../public');
const port = process.env.PORT || 3000;
var app = express();
var server = http.createServer(app);
var io = socketIO(server);
app.use(express.static(publicPath));
io.on('connection', (socket) => {
console.log('New user connected');
socket.emit('newMessage', generateMessage('Admin', 'Welcome to the chat app'));
socket.broadcast.emit('newMessage', generateMessage('Admin', 'New user joined'));
socket.on('createMessage', (message, callback) => {
console.log('createMessage', message);
io.emit('newMessage', generateMessage(message.from, message.text));
callback('This is from the server.'); //客户端执行回调函数
// socket.broadcast.emit('newMessage', {
// from: message.from,
// text: message.text,
// createdAt: new Date().getTime()
// });
});
socket.on('disconnect', () => {
console.log('User was disconnected');
});
});
server.listen(port, () => {
console.log(`Server is up on ${port}`);
});
测试
运行:
> node server/server.js
分别打开两个浏览器tabs,
打开localhost:3000查看控制台输出的语句。
经纬度
index.js
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 () {
});
});
var locationButton = jQuery('#send-location');
locationButton.on('click', function () {
if (!navigator.geolocation) {
return alert('Geolocation not supported by your browser.');
}
navigator.geolocation.getCurrentPosition(function (position) {
socket.emit('createLocationMessage', {
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
}, function () {
alert('Unable to fetch location.');
});
});
index.html
<!DOCTYPE html> <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> <button id="send-location">Send Location</button> <script src="/js/index.js"></script> </body> </html>
message.js
var generateMessage = (from, text) => {
return {
from,
text,
createdAt: new Date().getTime()
};
};
module.exports = {generateMessage};
server.js
const path = require('path');
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const {generateMessage} = require('./utils/message');
const publicPath = path.join(__dirname, '../public');
const port = process.env.PORT || 3000;
var app = express();
var server = http.createServer(app);
var io = socketIO(server);
app.use(express.static(publicPath));
io.on('connection', (socket) => {
console.log('New user connected');
socket.emit('newMessage', generateMessage('Admin', 'Welcome to the chat app'));
socket.broadcast.emit('newMessage', generateMessage('Admin', 'New user joined'));
socket.on('createMessage', (message, callback) => {
console.log('createMessage', message);
io.emit('newMessage', generateMessage(message.from, message.text));
callback('This is from the server.');
// socket.broadcast.emit('newMessage', {
// from: message.from,
// text: message.text,
// createdAt: new Date().getTime()
// });
});
socket.on('createLocationMessage', (coords) => {
io.emit('newMessage', generateMessage('Admin', `${coords.latitude}, ${coords.longitude}`));
});
socket.on('disconnect', () => {
console.log('User was disconnected');
});
});
server.listen(port, () => {
console.log(`Server is up on ${port}`);
});
谷歌经纬度
index.js
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);
});
socket.on('newLocationMessage', function (message) {
var li = jQuery('<li></li>');
var a = jQuery('<a target="_blank">My current location</a>');
li.text(`${message.from}: `);
a.attr('href', message.url);
li.append(a);
jQuery('#messages').append(li);
});
jQuery('#message-form').on('submit', function (e) {
e.preventDefault();
socket.emit('createMessage', {
from: 'User',
text: jQuery('[name=message]').val()
}, function () {
});
});
var locationButton = jQuery('#send-location');
locationButton.on('click', function () {
if (!navigator.geolocation) {
return alert('Geolocation not supported by your browser.');
}
navigator.geolocation.getCurrentPosition(function (position) {
socket.emit('createLocationMessage', {
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
}, function () {
alert('Unable to fetch location.');
});
});
index.html
<!DOCTYPE html> <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> <button id="send-location">Send Location</button> <script src="/js/index.js"></script> </body> </html>
message.js
var generateMessage = (from, text) => {
return {
from,
text,
createdAt: new Date().getTime()
};
};
var generateLocationMessage = (from, latitude, longitude) => {
return {
from,
url: `https://www.google.com/maps?q=${latitude},${longitude}`,
createdAt: new Date().getTime()
};
};
module.exports = {generateMessage, generateLocationMessage};
server.js
const path = require('path');
const http = require('http');
const express = require('express');
const socketIO = require('socket.io');
const {generateMessage,generateLocationMessage} = require('./utils/message');
const publicPath = path.join(__dirname, '../public');
const port = process.env.PORT || 3000;
var app = express();
var server = http.createServer(app);
var io = socketIO(server);
app.use(express.static(publicPath));
io.on('connection', (socket) => {
console.log('New user connected');
socket.emit('newMessage', generateMessage('Admin', 'Welcome to the chat app'));
socket.broadcast.emit('newMessage', generateMessage('Admin', 'New user joined'));
socket.on('createMessage', (message, callback) => {
console.log('createMessage', message);
io.emit('newMessage', generateMessage(message.from, message.text));
callback('This is from the server.');
// socket.broadcast.emit('newMessage', {
// from: message.from,
// text: message.text,
// createdAt: new Date().getTime()
// });
});
socket.on('createLocationMessage', (coords) => {
io.emit('newLocationMessage', generateLocationMessage('Admin', coords.latitude, coords.longitude));
});
socket.on('disconnect', () => {
console.log('User was disconnected');
});
});
server.listen(port, () => {
console.log(`Server is up on ${port}`);
});
页面优化
css/style.css:
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
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);
});
socket.on('newLocationMessage', function (message) {
var li = jQuery('<li></li>');
var a = jQuery('<a target="_blank">My current location</a>');
li.text(`${message.from}: `);
a.attr('href', message.url);
li.append(a);
jQuery('#messages').append(li);
});
jQuery('#message-form').on('submit', function (e) {
e.preventDefault();
socket.emit('createMessage', {
from: 'User',
text: jQuery('[name=message]').val()
}, function () {
});
});
var locationButton = jQuery('#send-location');
locationButton.on('click', function () {
if (!navigator.geolocation) {
return alert('Geolocation not supported by your browser.');
}
locationButton.attr('disabled', 'disabled').text('Sending location...');
navigator.geolocation.getCurrentPosition(function (position) {
locationButton.removeAttr('disabled').text('Send location');
socket.emit('createLocationMessage', {
latitude: position.coords.latitude,
longitude: position.coords.longitude
});
}, function () {
locationButton.removeAttr('disabled').text('Send location');
alert('Unable to fetch location.');
});
});
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。