Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nodejs作為server在超過24人連線時同步會產生延遲 #35

Open
z20818z opened this issue Jan 3, 2020 · 5 comments
Open

nodejs作為server在超過24人連線時同步會產生延遲 #35

z20818z opened this issue Jan 3, 2020 · 5 comments

Comments

@z20818z
Copy link

z20818z commented Jan 3, 2020

感謝使用 Node.js Taiwan AMA,以下附上簡單提問範例供參考,請把內容改成你自己遇到的問題

目的

<<我希望做一個 多人上線的遊戲伺服器 ,達成即時同步的效果>>

使用的工具

<<我在 Windows 下使用 npm 安裝 node.js 10.16 >>

操作流程

<<我下了 node dive_server.js 運行>>

遇到的問題

<<少人連線的時候不會出現延遲,但是在超過24人連線之後她會出現延遲的現象>>

嘗試過的解法

<<我嘗試過把 變數減少,但是在運行超過28台主機的時候便會出現延遲>>

程式碼

data_object.js

this.server_update = function(id,value){                             
	   socket.emit('update_data',{  
	                  'room_id':self.room_id, 
			 'player_data':id,
			 'get_value':value,
		         'get_number':value_object['player_num']});    
	}

dive_server.js

var express = require("express");
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http,{
  pingInterval: 1000,
  pingTimeout: 2000
});
var mysql = require('mysql');

var con;
var db_config = {
  host: "localhost",
  user: "root",
  password: "",
  post:'3306'
};
app.use(express.static('public'));						  
  socket.on('update_data',function(data){
         Object.keys(data).forEach(function(key) {  // 逐行列出標頭
           switch(key){
            case 'join_room':
              socket.join(data.room_id);               //連線時候4人順便將它設定群組
              socket.join(data.join_same_team);             //同對1房間
              break;
            case 'player_data':
              var attr_data = { 'id':data['player_data'],
                                'value':data['get_value']};							   
              io.to(data.room_id).emit('other_player_change', attr_data);             //將資訊傳給其他連線者的的IO
              break;
            case 'player_data_only':         //不傳給自己
              var attr_data = { 'id':data['player_data_only'],
                                'value':data['get_value']};							   
              socket.broadcast.to(data.room_id).emit('other_player_change', attr_data);             //將資訊傳給其他連線者的的IO
              break;
            case 'same_team':
              var attr_data = { 'id':data['same_team_id'],
                                'value':data['get_value'],
                        'another_value':data['another_value']};								   
              io.to(data.same_team).emit('other_player_change', attr_data);             //將資訊傳給同隊友
              io.to(data.another_team).emit('other_player_change', { 'id':data['same_team_id'],'value':data['another_value']});//將資訊傳給另外一隊同隊友
              break;
            case 'team_msg':
              var attr_data = {'msg':data.msg,
                                'nickname':data.nickname,
                        'index':data.index};	
              io.to(data.team_msg).emit('team_msg', attr_data);             //將資訊傳給同隊友
              break;
            case 'same_team_game_over':
                var attr_data = { 'dead':data['dead']};								   
                io.to(data.room_id).emit('game_over_msg', attr_data);             //將資訊傳給其他連線者的dive的IO
                break;
            }
       
          })
  });

html js

var pass = player_one_value[1];   // 裡面有十幾個變數

for(var e = 0;e<pass.length;e++){
	var value = diveLinker.getAttr(pass[e]);
	if(data_array[e] != value){
		project_data.server_update_only(pass[e],value);
	}else{
		data_array[e] = value;
	 } 
}
@fillano
Copy link

fillano commented Jan 3, 2020

  1. 請量化問題,例如所謂的延遲,是延遲多少,在多少連線時,會有多少的延遲等
  2. 你怎麼測試這些連線的?用28台不同機器打一台伺服器?
  3. 有監看CPU跟記憶體使用的狀況嗎?
  4. 可以用Profiling工具來找可能的瓶頸點,例如clinic.js等,請google一下

@z20818z
Copy link
Author

z20818z commented Jan 4, 2020

  1. 請量化問題,例如所謂的延遲,是延遲多少,在多少連線時,會有多少的延遲等
  2. 你怎麼測試這些連線的?用28台不同機器打一台伺服器?
  3. 有監看CPU跟記憶體使用的狀況嗎?
  4. 可以用Profiling工具來找可能的瓶頸點,例如clinic.js等,請google一下

1.延遲是latency會在24人連線後數據同步時有100-200不等的延遲 28之後會開始飆升至1000 甚至更高
2.我開了28台電腦連線到server上面進行遊戲
3.cpu使用率在50%以下 記憶體使用率為50%左右
4.我這幾天嘗試看看
目前的想法是 可能是js裡面的for迴圈在每一個frame進行同步所以造成socket堵塞?

@fillano
Copy link

fillano commented Jan 4, 2020

一個寫法的建議:
可以考慮切出更多的on(event, data=>{})之類,讓他可以更快處理完,這樣雖然程式看起來比較複雜,但是比較不會擋到event loop,使得latency比較快速累積。畢竟不管多少連線,都是共用一個event loop,只用一個update_data事件來處理所有的資料,可能會比較慢。

不過還是用Profiling的方式來確定問題會比較準。

@poying
Copy link

poying commented Jan 5, 2020

cpu 使用率看起來不高,可以用 cluster module(mp2 的 cluster mode)來提高 cpu 使用率。用 cluster module 時,socket.io 的應該會需要用 redis adapter。

@clonn
Copy link
Member

clonn commented Jan 6, 2020 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants