此博客案例是为方便自己查看,给的代码不全可能无法一下看懂,如果不了解Sproto协议的,可以先看下这篇文章:https://blog.csdn.net/sindyra/article/details/108423417 这里我们主要挑出客户端与服务端实际通信时RPC案例讲解下,本案例是一个登陆注册的案例。
1.首先是客户端向服务端发送请求:
local login_args = {name="Bob",password="123456"} local str = request("login",login_args,session_id) --参数分别为 name ,args , sessionname 是消息的字符串名(其实就是消息的类型,如登录消息,授权消息等)、args 是一张保存用消息内容的 table ,而 session 是你提供的唯一识别号,用于让对方正确的回应。 当你的协议不规定需要回应时,session 可以不给出。同样,args 也可以为空。
2.服务器接受到协议:
local function read (fd, size) return socket.read (fd, size) or error () end local function read_msg (fd) local buf = read (fd, 2) --使用小端读取方式,高地址存高位 local protocal_len = buf:byte(1) + buf:byte(2) * 256 --头2字节表示协议总长度 = 协议总长度(2字节)+协议号(2字节)+消息长度 --local protocal_length = string.unpack ("<H", buf) --H代表无符号short,h代表有符号short skynet.error("recevied msg:") skynet.error("protocal length:"..protocal_len) buf = read (fd, protocal_len) local msg_len = protocal_len - 4 --分割协议,去除协议长度(2字节)和协议号(2字节),只留下消息内容,而消息内容的前2字节也去掉,- --它是字段的数量。字段部分中的每个字段都是一个16位整数(n)。如果n为零,则表示字段数据在数据- --部分被编码; --所以2+2+2=6,即真正消息内容的起始位置为7 local msg = buf:sub(7, protocal_len) --sub(起始位置,结束位置) skynet.error("msg:"..msg) return host:dispatch (msg) end3.服务器回复消息:
socket.start (fd) local type, name, args, response = read_msg (fd) --type请求类型(request...),name消息的类型名(.auth...) skynet.error("type:"..type) skynet.error("name:"..name) skynet.error("username:"..args.name) --read_msg (fd) --type请求类型(request...),name消息的类型名(.auth...) assert (type == "REQUEST") if name == "login" then local user_name = args.name local user_password = args.password skynet.error("username:",user_name) skynet.error("password:",user_password) for key, value in pairs(user_list) do if value.name == user_name and value.password == user_password then local msg = response { user_exists = true, session = 1, } skynet.error("login success!") send_msg (fd, msg) return end end --如果没有找到用户名和密码,登陆失败 local msg = response { user_exists = false, } skynet.error("login failed!") send_msg (fd, msg) end
