This note aims to show you some aspects of our project: problems, solutions, tools, and necessary knowledge for those who may concern.
I. New design, new look.
I have a task of making html, css which is based on Viet's photoshop. However, the original design did not look impressive too much then I tried to make it better. Now it looks like below.
For log in and register screen:
For home screen:
And finally, for the game screen:
They work well for both desktop and mobile devices, and of course, I have completed integrating this new design together with code.
II. Problems in current version.
After reading code of the current version (last updated from Viet), I realize that there are many problems even though its logic is working quite well. The reason I point out these problems here is that I'like to share my actual experience in programming or the way I start approaching a complete project that I haven't had any experience before.
1. Remove the redundancy.
a) Node module.
As we know, removing redundant module is necessary. Before importing any modules, we need to find out its purpose first and tried to ask yourself whether there is another way to accomplish it without that library.
body-parser: This module is only need in express 4.0 or above (but it is not recommended to use). For express below 4.0, the express module have already supported 'body parser' for POST request. Just add these code:
app.use(express.urlencoded());
app.use(express.json());
instead of:
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
Therefore we can remove module 'body-parser' from package.json now.
ejs: This module has the same purpose with jade (template engine) and you are using it with only purpose is to render html file??
Html is not a template so we don't need to render.
Just need to call : res.sendfile('login.html');
Instead of calling: res.render('login.html') and using ejs
Again, we can remove ejs from package.json.
b) Session problem.
We all know what session is, but in some cases we didn't use it correctly. Let me clarify its definition and the difference between it and global variable.
Global variables are shared variable between every users. Conversely, session is used to store information of only one user between pages.
In current version, inside index.js file, (var user) is global variable or (var onlineList) is global variable. It can be used from all users with the same value.
You are doing correctly when using req.session.user for every GET or POST request. However, in io.sockets.on('connection', function (socket))....
You had a mistake that you used global variable 'user' and not use session for that. The logic may have problem if we have lot of people trying to connect at the same time (e.g 10 users).
Unfortunately, we can't call req.sesison inside IO socket. To accomplish that, we need to make a handshake (we can call it: bridge). Now req.session.user can be replace by socket.handshake.session.user.
You can see the handshake function (bridge) inside index.js and believe that there will be no problem with session anymore.
c) Code style
A clear code help other members understand what you have done.
I don't appreciate the skill of the original owner of this project. He made some messes in his code and when you add your own code without any rules then I have lost in your code, too.
- In database, in table 'account', you have column name 'gameId'.
For example: "gameId": "60722_JqY6ItKJI5NCV_1LxuG1"
The interesting thing is you added the socket_id to game_id and you never use it. The string '60722_JqY6ItKJI5NCV_1LxuG1' is irrelevant to game_id so if you want to store its socket id, you should add new column.
- You create status with 2 value 'create_game' and 'playing' but you never use it. It is interesting, too.
- Variable Socket_id and player_id has the same value so we don't need to mention both of them in our code, it makes a mess. Just pick one of them.
- Remove unnecessary function in scripts, files and template in index.jade:
If we don't use any functions, files or template, we should remove them. Other members will not need to care about them.
- How to store data in html tag:
Currently, I see that you often store information such as room number in id attribute...
<button id="60722_JqY6ItKJI5NCV_1LxuG1" class="btn btn-row join-btn">Join</button>
Well, there is a better way to store data, easier to understand that is we can add attribute data-xxx to html tag.
E.g: <div id='user1' data-online='false' data-socket-id='123r435454' .... </div>
In this way, we can store as many data as we want and then we don't need to worry that we are using id attribute for irrelevant purpose.
d) Bugs
Well, bugs everywhere, I detected dozens of bugs in the current version. I only list some of them and share my solution following:
Bug 1:
- User 1 log in, create game and waiting.
- User 2 logi n, join the room of user 1.
The result is: in game screen, there is no player name for user 1 and the score is still 0 all the time.
Wrong logic.
Bug 2:
User logs in successfully then close the window without logging out. The database still says this user is 'online'. This could produce lots of bugs. E.g: other users log in and they still see him in their online list. In the worse case, they tried to join his room (bad luck because he is not online).
Bug 3:
- User 1 log in, user 2 login.
- User 1 create game, user 2 join user 1's room.
- Whey they are playing, user 2 refresh the screen.
The result is: user 2 can still join user 1's room even though user1 is playing. There is no player name for user 1 and the score is still 0 all the time (like bug 1).
Bug 4: Many functions repeat twice.
When dealing with socket io, we need to be aware of the danger of broadcast function. In one room, e.g we have 3 users are playing, these users want to get the new word for next round. Then only one player (HOST) request the server for it and the server will broadcast the word to every members in group.
Look at the photo below:
The button is generated twice, means that logic repeated twice in many functions. I can see that when debugging app.js script. It is dangerous.
Bug 5:
In file agxgame.js and function: sendWord(wordPoolIndex, gameId)
var data = getWordData(wordPoolIndex);
io.sockets.in(data.gameId).emit('newWordData', data);
data variable has no property 'gameId'. Therefore, when sending information to room data.gameId server will send the information to all rooms.
Solution: change from data.gameId to gameId.
And there were many many bugs when I tried to connect 3 or more users. Finally, I didn't rely on the existing code and made my own structure. I was not able to fix these bugs if I still kept the old structure.
III. Tools
It is important to find out some helpful tools regarding what we are doing.
- To show and edit data in mongodb with a nice graphic interface. We have mongo-express, check it here:
https://github.com/andzdroid/mongo-express
- To debug script in server side, we have node-inspector, check it here:
https://github.com/node-inspector/node-inspector
- And of course, to debug script in client side, it is always supported by every browsers. Just press F12.
IV. My new source code.
Here is my latest source code from github and you can get it by:
git clone https://github.com/phuongdong008/anagrammatix
The reason why I didn't merge my code to Viet's code is that they're different in structure then I don't want to see any conflicts.
There are still bugs in my version but they are not serious. You are welcome to check it.
My experience:
I do not make this note for proving anything. Maybe we are not good at programming but we need to have a good problem solving skills. It is not about trying to make it done and finally get no value experience. It is about thinking of our situation, problem carefully before starting to do anything further.
Many people think that they don't need to research much, just need to make it work and finally they will modify their code later. However, they have lost in their code and when big bugs appear, they can't fix them because their structure is a mess in the beginning.
Note: This is only my additional work. Tasks assigned to me will be done according to our plan.