探索使用 Golang 和 Webassembly 构建一个多人游戏服务器
什么是 WebAssembly
?由 Google
、Microsoft
、Mozilla
、Apple
等发起的 WebAssembly
是一种新的字节码格式,主流浏览器都已经支持 WebAssembly
。 和 JS
需要解释执行不同,WebAssembly
字节码和底层机器码很相似可快速装载运行,因此性能相对于 JS
解释执行大大提升。WebAssembly
并不是一门编程语言,而是一份字节码标准,需要用高级编程语言编译出字节码放到 WebAssembly
虚拟机中才能运行。
Panzr.io 简介
- 基于开源技术的游戏
- 使用
Web
作为发行平台 - 轻巧快速
- 探索基本的多人游戏技术
- 扩展
Go
技术知识
Panzr.io 架构
Panzr.io 部署架构
Triebwerk 简介
项目源码:
项目 Status:
Triebwerk
是一个开源的多人游戏服务器- 使用
Go
语言编写 - 目前仅是基础原型
游戏是如何运行的?
服务器权威架构
- 仅通过服务器进行通讯
- 客户端将所有输入发送到服务器
- 服务器有权进行模拟
- 防止作弊并引入延迟
客户端预测和服务器协调
- 最早由
QuakeWorld
推广 - 本地模拟运动
- 不断与服务器状态同步
- 根据服务器状态更正本地状态
客户端插值
- 网络更新(
Updates
) < 每秒帧数(Frames
) - 过去状态之间的插值
- 保守算法
- 没有推断
定义边界
限制:
- 所有游戏逻辑仅在
2D
空间中 - 均匀表面
- 仅通过键盘进行输入控制
- 限制地图尺寸
- 缓慢移动的车辆
- 没有物理引擎
服务器实现
玩家移动
碰撞检测
二进制数据传输
- 最小化资源使用
- 防止数据包分段
- 最小化丢包的影响
WebAssembly 模块
游戏逻辑(Game logic
):Server
-> Client
- 文件大小 > 2MB
- 服务器和客户端根据相同的逻辑计算状态
- 通过二进制类型进行数据传输
编译:
GOOS=js GOARCH=wasm go build -o tanks.wasm cmd/wasm/tanks.go
Client:
<script src="/game/wass_exec.js"></script>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(featch("/game/tanks.wass"), go.importObject).then(result => {
go.run(result.instance);
});
</script>
Server:
js.Global().Set("updateNetworkPlayer", js.FuncOf(updateNetworkPlayer))
在 Go 中编码 state
posX := float32(30.457777)
posY := float32(10.336666)
buf := make([]byte, 8)
binary.LittleEndian.PutUint32(buf[0:], math.Float32bits(posX))
binary.LittleEndian.PutUint32(buf[4:], math.Float32bits(posY))
var uint8Array = js.Global().Get("Uint8Array")
dst := uint8Array.New(len(buf))
js.CopyBytesToJS(dst, buf)
在 Javascript 中解码 state
let dv = new DataView(state.buffer)
let posX = dv.getFloat32(0, true)
let posY = dv.getFloat32(4, true)
在线试玩
Refs
我是为少
微信:uuhells123
公众号:黑客下午茶
加我微信(互相学习交流),关注公众号(获取更多学习资料~)
探索使用 Golang 和 Webassembly 构建一个多人游戏服务器的更多相关文章
- 使用.net core在Ubuntu构建一个TCP服务器
介绍和背景 TCP编程是网络编程领域最有趣的部分之一.在Ubuntu环境中,我喜欢使用.NET Core进行TCP编程,并使用本机Ubuntu脚本与TCP服务器进行通信.以前,我在.NET框架本身写了 ...
- Linux上构建一个RADIUS服务器详解
作为一名网络管理员,您需要为您所需管理的每个网络设备存放用于管理的用户信息.但是网络设备通常只支持有限的用户管理功能.学习如何使用Linux上的一个外部RADIUS服务器来验证用户,具体来说是通过一个 ...
- 用java语言构建一个网络服务器,实现客户端和服务器之间通信,实现客户端拥有独立线程,互不干扰
服务器: 1.与客户端的交流手段多是I/O流的方式 2.对接的方式是Socket套接字,套接字通过IP地址和端口号来建立连接 3.(曾经十分影响理解的点)服务器发出的输出流的所有信息都会成为客户端的输 ...
- 使用promise构建一个向服务器异步数据请求
function getJSON(Url){ return new Promise((resolve,reject)=>{ request= new XMLHttpRequest(); requ ...
- Android学习笔记-构建一个可复用的自定义BaseAdapter
转载自http://www.runoob.com/w3cnote/android-tutorial-customer-baseadapter.html 作者:coder-pig 本节引言: 如题, ...
- Python 之父再发文:构建一个 PEG 解析器
花下猫语: Python 之父在 Medium 上开了博客,现在写了两篇文章,本文是第二篇的译文.前一篇的译文 在此 ,宣布了将要用 PEG 解析器来替换当前的 pgen 解析器. 本文主要介绍了构建 ...
- 如何构建一个多人(.io) Web 游戏,第 2 部分
原文:How to Build a Multiplayer (.io) Web Game, Part 2 探索 .io 游戏背后的后端服务器. 上篇:如何构建一个多人(.io) Web 游戏,第 1 ...
- CloudBase CMS + Next.js:轻松构建一个内容丰富的站点
项目背景 试想一下,如果你现在要为你自己或者你所在的组织创建一个强内容的站点,同时要求好的 SEO(搜素引擎优化),比如博客,你会怎么做呢? 由 vite 或者 create-react-app 等脚 ...
- 开源低代码平台开发实践二:从 0 构建一个基于 ER 图的低代码后端
前后端分离了! 第一次知道这个事情的时候,内心是困惑的. 前端都出去搞 SPA,SEO 们同意吗? 后来,SSR 来了. 他说:"SEO 们同意了!" 任何人的反对,都没用了,时代 ...
随机推荐
- Linux关机指令详解
Linux关机指令 在linux领域内大多用在服务器上,很少遇到关机的操作.毕竟服务器上跑一个服务是永无止境的,除非特殊情况下,不得已才会关机. 正确的关机流程为:sync > shutdown ...
- 剑指 Offer 53 - II. 0~n-1中缺失的数字 + 二分法
剑指 Offer 53 - II. 0-n-1中缺失的数字 Offer_53 题目详情 java代码 package com.walegarrett.offer; /** * @Author Wale ...
- 记一次Linux内核崩溃:kdump,crash,vmcore
原理 Linux内核发送崩溃时,kdump会生成一个内核转储文件vmcore. 可以通过分析vmcore分析出内核崩溃的原因. crash是一个被广泛应用的内核奔溃转储文件分析工具.使用crash调试 ...
- 测试平台系列(1) 搭建Flask服务
搭建Flask服务 项目地址 点我进入项目地址 代码都会在这里有所展示,喜欢的话可以帮点个star,谢谢大家了!如果你喜欢该教程,也可以分享给其他人. 关于选型 想了很久,本来打算用「Gin」做为后端 ...
- JavaScript数组的几个常用的API
一. 扁平化嵌套数组/展平和阵列孔--flat() 1.实现效果 var arr1 = [1, 2, [3, 4]]; arr1.flat(); // [1, 2, 3, 4] var arr2 = ...
- vue Element-ui el-menu 左侧导航条
<template> <!--实现左侧导航条动态渲染(三级)--> <el-menu class="el-menu-vertical-demo" @o ...
- Qt update刷新之源码分析总结
大家好,我是IT文艺男,来自一线大厂的一线程序员 经过前面几次的Qt源码讲解,我相信大家对Qt update刷新机制从底层原理上有了一个深刻的理解:这次做一个收尾总结,来复盘前面几次所讲解的内容: 分 ...
- Hi3559AV100 NNIE开发(6)RFCN中NNIE实现关键线程函数->SAMPLE_SVP_NNIE_Rfcn_ViToVo()进行数据流分析
前面随笔给出了NNIE开发的基本知识,下面几篇随笔将着重于Mobilefacenet NNIE开发,实现mobilefacenet.wk的chip版本,并在Hi3559AV100上实现mobilefa ...
- 策略枚举:消除在项目里大批量使用if-else的正确姿势
文/朱季谦 想起刚开始接触JAVA编程的时候,若遇到大量流程判断语句,几乎满屏都是if-else语句,多得让自己都忘了哪里是头,哪里是尾,但是,纵然满屏是if-else,但彼时也没有觉得多别扭.等到编 ...
- matplotlib常规使用方法
1,指定图片大小和像素 Python绘图问题:Matplotlib中指定图片大小和像素 2,绘图命令的基本架构及其属性设置 绘图与可视化 3,python基础语法(二)--- plt的一些函数使用 p ...