python - 提高套接字速度
问题描述
我正在开发一个带有套接字的多人游戏,并决定测试从另一台机器连接到服务器。我能够连接到服务器,但唯一的问题是有一点延迟。其他玩家会停下来,然后他们会传送回他们应该在的地方。这些不是很大的尖峰,它只会持续大约 4/6 秒,但很明显。我知道当我扩展游戏时,服务器会更慢到几乎无法玩的地步,所以我在这里询问希望找到加速服务器的好方法。我做了一些速度测试,这就是我得到的:
# Buffer recv - 0.015977859497070312
# update_client - typically around 0.00017213821411132812, but sometimes spikes to 9.202957153320312e-05
# sending data - around 0.0001914501190185547, but every other time, it spikes to 8.416175842285156e-05
这不是很多,但它可能会有所帮助。这是上面每个测试的代码。
接收缓冲区代码:
data = ""
recv_data = conn.recv(bufsize)
if recv_data == b'':
print(f"{player_id} DISCONNECTED")
break
message_length = int(recv_data[:HEADER_SIZE])
data += recv_data.decode()
while True:
if len(data)-HEADER_SIZE >= message_length:
if len(data)-HEADER_SIZE > message_length:
conn.setblocking(0)
while True:
try:
extra_data = conn.recv(bufsize)
if not extra_data:
break
except:
break
conn.setblocking(1)
break
recv_data = conn.recv(bufsize)
data += recv_data.decode()
data = data[HEADER_SIZE:message_length+HEADER_SIZE]
Update_client 代码(我为每个客户端使用一个新线程)
def update_client(updatemessage,target_socket):
"""
update_data[0][0] is the player's x pos
update_data[0][1] is the player's y pos
update_data[1] is the player's flip bool
update_data[2] is the player's name str
:param updatemessage:
:param target_socket:
:return:
"""
# player key structure in playermap: {playerid:[[x,y],flip,name,been_hit]}
update_data = json.loads(updatemessage) # Data received from the passed client
updates = [key for key in update_data.keys()] # All keys in the dict sent from client
player_update_lst = update_data[updates[0]] # Player locations update data
mini_update_lst = update_data[updates[1]] # Mini game update data
playerid = player_update_lst[0] # The id of the player client sending this data
if playerid == 0: # Prevent sending data to the server itself
return
update = {'player locations':[],"mini-update":[]} # Empty update dict
if start_game and playerid not in updated_clients:
update["map-update"] = start_game[1]
updated_clients.append(playerid)
if sorted([key for key in playermap.keys()]) == sorted(updated_clients):
print("Clearing")
start_game.clear()
updated_clients.clear()
if playerid != 1:
if playerid not in playermap.keys():
playerid -= 1
elif playerid - 1 not in playermap.keys():
pdata = playermap[playerid]
playermap.pop(playerid)
playerid -= 1
playermap[playerid] = pdata
update = {"id update":playerid,'player locations':[],"mini-update":[]}
else:
if mini_update_lst[2]:
minigame, minimap = get_minimap()
update["map-update"] = minimap
start_game.append(minigame)
start_game.append(minimap)
print("starting game")
# Player locations update stuff
playermap[playerid][0][0] = player_update_lst[1] # player.x
playermap[playerid][0][1] = player_update_lst[2] # player.y
playermap[playerid][1] = player_update_lst[3] # player.flip
playermap[playerid][2] = player_update_lst[4] # player.name
playermap[playerid][4] = player_update_lst[5] # player.been_hit
# Mini game update stuff
hit_player = mini_update_lst[0] # hit_player (the id of the player that the client hit)
if hit_player:
playermap[hit_player][3] = playermap[playerid][0] # Goes to the id of the hit player in playermap and changes the "False"
# value at index 3, to the position of the player that hit the other player.
playermap[playerid][5] = mini_update_lst[1] # player.score (KOTH: The time in seconds the player has been on the platform)
# Looping over every connected player to send to the selected client. Used for changes to the player's position or look.
# (by "look", I mean the flip value which flips the player's image, and the hit value which changes the player img's hue)
score_update_lst = []
for key, value in playermap.items():
# key is the player's id
# value[0][0] is the player's x position
# value[0][1] is the player's y position
# value[1] is the player's flip value
# value[2] is the player's name
# value[3] is the player's attacker pos value (stores the position of the attacker if hit)
# value[4] is the player's been_hit value (used for the player flash when hit)
# value[5] is the player's score value (used for minigames)
update['player locations'].append([key, value[0][0], value[0][1], value[1], value[2], value[4]])
score_update_lst.append([value[2],value[5]])
update["mini-update"].append(score_update_lst)
# Knockback stuff. If the player has been hit, the position of the attacker will be stored at playermap[playerid][3].
# If there is data there, the code in the if statement is excuted
if playermap[playerid][3]:
update['mini-update'].append(playermap[playerid][3])
playermap[playerid][3] = False
else:
update['mini-update'].append(False)
# Sending the data to the client, but if there is a error, the client socket is removed
try:
#print(json.dumps(update).encode())
send_data = json.dumps(update)
target_socket.sendall((f"{len(send_data):<{HEADER_SIZE}}"+send_data).encode())
except Exception as e:
print(f"Error: {e}")
return playerid
发送数据代码:
try:
#print(json.dumps(update).encode())
send_data = json.dumps(update)
target_socket.sendall((f"{len(send_data):<{HEADER_SIZE}}"+send_data).encode())
except Exception as e:
print(f"Error: {e}"
有谁知道如何使这些代码片段更快?如果您需要额外的信息或代码,请随时询问:)。
解决方案
推荐阅读
- swift - 有没有办法在同一个 XCODE 项目中重用代码?
- javascript - Codemirror Clike 模式似乎不起作用
- c++ - std::function 中不允许引用返回类型吗?
- javascript - 将对象传递给函数以进行 API 调用
- python - TypeError:&:'str'和'method'不支持的操作数类型
- javascript - 如何更新 React 状态中的单个属性(功能组件)
- arrays - 如何使用 Go 将此 JSON 数组解组为结构切片?
- c++ - 用ar编译归档,手动编译,ld找不到
- python - 缺少 __RequestVerificationToken 以使用外部求解器绕过谷歌验证码
- angular - 错误 Web App Angular 2 IE 11 和 Edge 错误