socket.io

项目目录

├── package-lock.json
├── package.json
├── public
│   └── index.html
└── server
└── server.js

初始化

npm init
npm install --save express

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>

<html>

<head>
<meta charset="utf-8">
</head>

<body>
<p>Welcome to the chat app</p>
</body>

</html>

server.js

1
2
3
4
5
6
7
8
9
10
11
12
13
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"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

1
2
> heroku create
> git push https://git.heroku.com/rocky-shore-24556.git

使用socket.io

安装:

1
npm install -save socket.io

socket.io可以让服务器与客户端相互连接并触发事件。下例测试连接与断开服务器

server.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
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!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即可运行,查看控制台输出的语句。

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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:

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
30
31
32
33
34
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即可运行,查看控制台输出的语句。

1
> node server/server.js

广播

当客户端连接服务器之后,所有的节点即会触发newMessage事件,但是当前连接的客户端与其他客户端接受的信息不相同。
当前客户端接受:Welcome to the chat app
其他客户端接受:New user joined

index.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!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

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

server.js:

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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}`);
});

测试

运行:

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
<!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
    
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
2
3
4
5
6
7
8
9
var generateMessage = (from, text) => {
return {
from,
text,
createdAt: new Date().getTime()
};
};

module.exports = {generateMessage};

server.js

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
30
31
32
33
34
35
36
37
38
39
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}`);
});

测试

运行:

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
<!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
    
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
2
3
4
5
6
7
8
9
var generateMessage = (from, text) => {
return {
from,
text,
createdAt: new Date().getTime()
};
};

module.exports = {generateMessage};

server.js

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
30
31
32
33
34
35
36
37
38
39
40
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}`);
});

测试

运行:

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
<!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
    
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
2
3
4
5
6
7
8
9
var generateMessage = (from, text) => {
return {
from,
text,
createdAt: new Date().getTime()
};
};

module.exports = {generateMessage};

server.js

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
30
31
32
33
34
35
36
37
38
39
40
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}`);
});

测试

运行:

1
> node server/server.js

分别打开两个浏览器tabs,
打开localhost:3000查看控制台输出的语句。

经纬度

index.js

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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

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

1
2
3
4
5
6
7
8
9
var generateMessage = (from, text) => {
return {
from,
text,
createdAt: new Date().getTime()
};
};

module.exports = {generateMessage};

server.js

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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:

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
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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.');
});
});