重磅!基于Lua的命令行远程打包系统(三)

上一节,亿元程序员为我们简单介绍了Lua运行环境的搭建,我们成功搭建了我们命令行远程打包系统的环境之后,下面我们就可以正式进入我们打包系统的搭建。下面我们跟随亿元程序员一起来看看。

远程打包系统的前后端通信

一.打包系统的后端搭建。

1.首先引入我们前后端通讯需要的socket库。
local socket = require("socket.core")
2.然后绑定端口并且监听连接
local function init()
	server_info.port = arg[2] or server_info.port
	server = socket.tcp() //创建socket
	local r,err=server:bind("*",server_info.port)	//绑定监听端口
	if err then
		log(string.format("端口%d绑定失败,请检查端口.",server_info.port))
		os.exit(1)
	end
	server:setoption("keepalive",true) //保持连接长期活跃
	server:listen(5) //监听
	server:settimeout(1,'b')
	log(string.format("远程打包服务器启动成功,绑定端口:%d.",server_info.port))
end
3.循环监听客户端连接和处理客户端请求
local function main_loop()
	while true do
		process_accept() //接受客户端连接
		local cur_time = os.time()
		while os.time()==cur_time do
			local read_array,write_array,errmsg =socket.select(select_array,select_array,1)
			if errmsg ~= nil and errmsg ~= "timeout" then
				log("error: "..errmsg)
			elseif errmsg ~= "timeout" then
				if #read_array ~= 0 then
					process_request(read_array) //处理客户端请求
				end
			end
		end 
	end
end
4.接受客户端连接
local function process_accept()
	local client,msg = server:accept() //接受客户端连接
	if client == nil  then
		if msg ~= "timeout" then
			log(msg)
		end
	else
		local ip,port=client:getpeername()

		local username =client:receive("*l")	
		local password =client:receive("*l")		
		
		if username == nil or password == nil then
			log("username == nil or password == nil")
			client:send("<fail>\n")
			client:close()
			return
		end
		if (ip == nil or port == nil ) then
			log("ip == nil or port == nil")
			client:send("<fail>\n")
			client:close()
			return
		end
		for _,_client in pairs(clients) do
			if (_client ~= nil and  _client.user == username) then
				client:send("<user_exist>\n")
				client:close()
				return
			end
		end

		local newc={conn=client,ip=ip, port=port,id=ip..port,user=username,cmd=""}
		log(string.format("用户:%s,IP:%s 连接成功.",username or "",ip or ""))
		clients[ip..port]=newc

		select_array[#select_array+1]= client
		newc.slot = #select_array

		client:send("<ok>\n")
		print_prompt(newc)
	end

end
5.处理客户端请求
local function process_request(read_array)
	for k=1,#read_array,1 do
		local socket = read_array[k]
		if(socket ~= nil) then
			local ip,port = socket:getpeername()
			if(port ~= nil and ip ~= nil ) then
				log(ip..":"..port)
				local client = clients[ip..port]
				if(client ~= nil) then
					local line,errmsg = client.conn:receive("*l") //接受客户端信息
					if  errmsg and errmsg ~= "timeout" or line =="<close>" then
						close_client(ip..port)
					elseif line then
						do_request(client,line) //处理客户端请求
					end
				end
			end
		end
	end 
end
6.响应客户端请求
local function do_request(client,line)

	build_service.client=client
	
	log(string.format("用户 %s 发送内容 %s.",client.user, line))

	output(string.reverse(line)) //将客户端的内容反转并发回客户端

	output("<send_over>")
	
end

function output(msg)
	log(msg)
	if build_service.client then
		send_msg(build_service.client,msg)
	end
end

local function send_msg(client, msg)
	if not client.conn then
		return
	end
	local c,err=client.conn:send(msg.."\n") //发送内容给客户端
	if err then
		log(err)
		close_client(client.id)
	end
end
7.启动服务端
init()
main_loop()
8.测试!

image

二.打包系统的前端搭建。

1.连接打包系统服务端
function init(host, port)
	local username = arg[1]
	local password = arg[2]
	if username == nil then
		output("请输入用户名")
		os.exit(1)
	end

	if password == nil then
		output("请输入密码!")
		os.exit(1)
	end


	host = arg[3] or "127.0.0.1"
	port = arg[4] or 6060
			
	g_client = socket.tcp() //创建sockt
	g_client:setoption("keepalive",true) //保持活跃

	if g_client:connect(host, port) then
		g_client:send(username..g_lf)
		g_client:send(password..g_lf)
		local msg, err = g_client:receive("*l") //接受服务器返回信息
		if err or  msg~="<ok>" then 
			if msg == "<fail>" then
				output(string.format("用户名与密码不匹配%s", msg))
			elseif msg == "<user_exist>" then
				output(string.format("不能连接服务器,用户重复登陆"))
			else
				output(string.format("不能连接服务器,%s.", msg or err ))
			end
			--sleep(1)
			os.exit(1)
		else
			output(string.format("成功连接服务器,%s,%s.",host,port))
			process_response() 
		end
	else
		output(string.format("不能连接服务器,%s,%s,请检查服务器是否启动.",host,port))
		os.exit(1)
	end
end
2.循环接收命令行输入的指令和接收服务端的信息
function main_loop()
	while true do
		process_request()
	end
end

function process_request()
	local line = io.read("*l") //接收命令行输入的指令
	
	if g_local_cmd[line] then 
		g_local_cmd[line]()
		print_prompt()
	else
		send_request(line) //发送指令到服务端
		
		process_response() //接收服务器端信息
		
	end	
end
3.发送指令到服务端
function send_request( msg)
	local c,err=g_client:send(msg..g_lf) //发送指令到服务端
	if err then
		close_connect()
		os.exit(1)
	end
end
4.接收服务端的消息
function process_response()
	while true do 
			echo = g_client:receive("*l")  //接受服务端信息
			if echo then 
				if echo=="<send_over>" then 
					break
				else
					output(echo)
					output("\n")
				end
			else
				break	
			end
	end
	print_prompt()
end
5.打印输出本地、服务器信息
function output(msg)
	io.stdout:write(msg) //将信息输出到命令行
end
6.启动客户端
init(host,port)
main_loop()
7.测试!

image

至此,亿元程序员已经为我们成功讲解了如何实现我们远程打包系统的简单的前后端通信。大家可以根据相关关键代码去实现,如果大家有不太理解或者遇到一些问题的,可以关注我们“亿元程序员”,并且尝试在聊天框中输入你遇到的问题,我们定会耐心地为你解答。下一篇文章我们将讲解如何接受客户端的指令并相应处理。喜欢的朋友们可以关注并且订阅。期待你的关注、收藏、转发、点赞、在看五连!谢谢大家!

需要本节完整源码的同学可以在聊天框输入 “lcrps03” 获取

推荐阅读:

重磅!基于Lua的命令行远程打包系统(一)

重磅!基于Lua的命令行远程打包系统(二)

重磅!基于Lua的命令行远程打包系统(三)

如此高端大气上档次的WOL网络唤醒一键遥控远程开机,想不想学?

网络唤醒的原理原来是这样的,GET!

学会远程开机之后,发现远程控制软件特别多,哪些好用?哪些免费?

如何让出差的女同事访问公司内网的svn?frp内网穿透可以帮到你

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亿元程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值