Skip to content
This repository was archived by the owner on Jan 8, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 2 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,6 @@
# ReactBlog
a blog system based on React+Node
node_chat分支


以[NodeBlog](https://github.com/BetaMee/NodeBlog)为基础,开发一个React+Node的blog系统,简单可易用的系统
以[NodeBlog](https://github.com/BetaMee/NodeBlog)为基础,开发一个React+Node的实时通信系统,使用WebSocket和Socket.io为包,后期准备独立出来,前期放在ReactBlog下。也学习下github分支管理

需求:

1. 完善的api接口,返回的是json数据,前端使用fetch获取数据。
2. 后期使用electron开发桌面应用,用于本地写博客。(或许我可以写一个像hexo那样的可以部署到github上的桌面应用)
3. 以我喜爱的material ui开发,后期设计自己的主题
4. 有用户权限
5. 留言系统就不自己做了
6. post模型和user模型
7. 正式部署到服务器上

未来计划:

1. electron桌面应用
2. 设计自己的主题风格
3. 开发部署工具,部署到github上,静态博客

步骤:
1. 先以NodeBlog为基础完善后台api设计.
2. 开发react的web页面,react-router作路由,前后端协作。
60 changes: 60 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
var http = require('http');
var fs = require('fs');
var path = require('path');
var mime = require('mime');
var cache = {};

function send404(response) {
response.writeHead(404, {'Content-Type': 'text/plain'});
response.write('Error 404: resource not found.');
response.end();
}

function sendFile(response, filePath, fileContents) {
response.writeHead(
200,
{"content-type": mime.lookup(path.basename(filePath))}
);
response.end(fileContents);
}

function serveStatic(response, cache, absPath) {
if (cache[absPath]) {
sendFile(response, absPath, cache[absPath]);
} else {
fs.exists(absPath, function(exists) {
if (exists) {
fs.readFile(absPath, function(err, data) {
if (err) {
send404(response);
} else {
cache[absPath] = data;
sendFile(response, absPath, data);
}
});
} else {
send404(response);
}
});
}
}

var server = http.createServer(function(request, response) {
var filePath = false;

if (request.url == '/') {
filePath = 'public/index.html';
} else {
filePath = 'public' + request.url;
}

var absPath = './' + filePath;
serveStatic(response, cache, absPath);
});

server.listen(3000, function() {
console.log("Server listening on port 3000.");
});

var chatServer = require('./lib/chat_server');
chatServer.listen(server);
112 changes: 112 additions & 0 deletions lib/chat_server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
var socketio = require('socket.io');
var io;
var guestNumber = 1;
var nickNames = {};
var namesUsed = [];
var currentRoom = {};

exports.listen = function(server) {
io = socketio.listen(server);
io.set('log level', 1);
io.sockets.on('connection', function (socket) {
guestNumber = assignGuestName(socket, guestNumber, nickNames, namesUsed);
joinRoom(socket, 'Lobby');
handleMessageBroadcasting(socket, nickNames);
handleNameChangeAttempts(socket, nickNames, namesUsed);
handleRoomJoining(socket);
socket.on('rooms', function() {
socket.emit('rooms', io.sockets.manager.rooms);
});
handleClientDisconnection(socket, nickNames, namesUsed);
});
};

function assignGuestName(socket, guestNumber, nickNames, namesUsed) {
var name = 'Guest' + guestNumber;
nickNames[socket.id] = name;
socket.emit('nameResult', {
success: true,
name: name
});
namesUsed.push(name);
return guestNumber + 1;
}

function joinRoom(socket, room) {
socket.join(room);
currentRoom[socket.id] = room;
socket.emit('joinResult', {room: room});
socket.broadcast.to(room).emit('message', {
text: nickNames[socket.id] + ' has joined ' + room + '.'
});

var usersInRoom = io.sockets.clients(room);
if (usersInRoom.length > 1) {
var usersInRoomSummary = 'Users currently in ' + room + ': ';
for (var index in usersInRoom) {
var userSocketId = usersInRoom[index].id;
if (userSocketId != socket.id) {
if (index > 0) {
usersInRoomSummary += ', ';
}
usersInRoomSummary += nickNames[userSocketId];
}
}
usersInRoomSummary += '.';
socket.emit('message', {text: usersInRoomSummary});
}
}

function handleNameChangeAttempts(socket, nickNames, namesUsed) {
socket.on('nameAttempt', function(name) {
if (name.indexOf('Guest') == 0) {
socket.emit('nameResult', {
success: false,
message: 'Names cannot begin with "Guest".'
});
} else {
if (namesUsed.indexOf(name) == -1) {
var previousName = nickNames[socket.id];
var previousNameIndex = namesUsed.indexOf(previousName);
namesUsed.push(name);
nickNames[socket.id] = name;
delete namesUsed[previousNameIndex];
socket.emit('nameResult', {
success: true,
name: name
});
socket.broadcast.to(currentRoom[socket.id]).emit('message', {
text: previousName + ' is now known as ' + name + '.'
});
} else {
socket.emit('nameResult', {
success: false,
message: 'That name is already in use.'
});
}
}
});
}

function handleMessageBroadcasting(socket) {
socket.on('message', function (message) {
socket.broadcast.to(message.room).emit('message', {
text: nickNames[socket.id] + ': ' + message.text
});
});
}

function handleRoomJoining(socket) {
socket.on('join', function(room) {
socket.leave(currentRoom[socket.id]);
joinRoom(socket, room.newRoom);
});
}

function handleClientDisconnection(socket) {
socket.on('disconnect', function() {
var nameIndex = namesUsed.indexOf(nickNames[socket.id]);
delete namesUsed[nameIndex];
delete nickNames[socket.id];
});
}
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"homepage": "https://github.com/BetaMee/ReactBlog#readme",
"dependencies": {
"express": "^4.14.1",
"express-session": "^1.15.1"
"express-session": "^1.15.1",
"mime": "^1.3.4",
"socket.io": "^1.7.2"
}
}
53 changes: 53 additions & 0 deletions public/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}

a {
color: #00B7FF;
}

#content {
width: 800px;
margin-left: auto;
margin-right: auto;
}

#room {
background-color: #ddd;
margin-bottom: 1em;
}

#messages {
width: 690px;
height: 300px;
overflow: auto;
background-color: #eee;
margin-bottom: 1em;
margin-right: 10px;
}

#room-list {
float: right;
width: 100px;
height: 300px;
overflow: auto;
}

#room-list div {
border-bottom: 1px solid #eee;
}

#room-list div:hover {
background-color: #ddd;
}

#send-message {
width: 700px;
margin-bottom: 1em;
margin-right: 1em;
}

#help {
font: 10px "Lucida Grande", Helvetica, Arial, sans-serif;
}
34 changes: 34 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!doctype html>
<html lang='en'>

<head>
<title>Chat</title>
<link rel='stylesheet' href='/stylesheets/style.css'></link>
</head>

<body>
<div id='content'>
<div id='room'></div>
<div id='room-list'></div>
<div id='messages'></div>

<form id='send-form'>
<input id='send-message' />
<input id='send-button' type='submit' value='Send'/>

<div id='help'>
Chat commands:
<ul>
<li>Change nickname: <code>/nick [username]</code></li>
<li>Join/create room: <code>/join [room name]</code></li>
</ul>
</div>
</form>
</div>

<script src='/socket.io/socket.io.js' type='text/javascript'></script>
<script src='http://code.jquery.com/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='/js/chat.js' type='text/javascript'></script>
<script src='/js/chat_ui.js' type='text/javascript'></script>
</body>
</html>
43 changes: 43 additions & 0 deletions public/js/chat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
var Chat = function(socket) {
this.socket = socket;
};

Chat.prototype.sendMessage = function(room, text) {
var message = {
room: room,
text: text
};
this.socket.emit('message', message);
};

Chat.prototype.changeRoom = function(room) {
this.socket.emit('join', {
newRoom: room
});
};

Chat.prototype.processCommand = function(command) {
var words = command.split(' ');
var command = words[0]
.substring(1, words[0].length)
.toLowerCase();
var message = false;

switch(command) {
case 'join':
words.shift();
var room = words.join(' ');
this.changeRoom(room);
break;
case 'nick':
words.shift();
var name = words.join(' ');
this.socket.emit('nameAttempt', name);
break;
default:
message = 'Unrecognized command.';
break;
};

return message;
};
Loading