zoukankan      html  css  js  c++  java
  • 跨平台高效率Lua网络库 ( 同步形式的API ,底层是异步非阻塞)

    Joynet

    项目地址:https://github.com/IronsDu/Joynet

    介绍

    high performance network library for lua, based on https://github.com/IronsDu/accumulation-dev and lua coroutine. Joynet 的网络底层使用多线程,但Lua (层面)是运行在单线程上。

    借助协程提供同步形式的API。(同步的socket api,同步的http api,同步的redis api)

    让应用业务开发更轻松,更爽!

    src 目录是此项目源代码, libs 目录为基于此Lua协程网络库开发的一些库

    构建

    • Windows : 在项目根目录中打开 Joynet.sln, 编译即可在当前目录产生可执行文件 Joynet
    • Linux : 在项目根本执行 make 即可生成可执行文件 Joynet

    使用

    examples 包含测试代码。 譬如我们要在Windows下运行PingPong测试: 先在项目根目录执行 Joynet examplesPingpongServer.lua,然后执行 Joynet examplesPingpongClient.lua

    一个小问题

    当前Joynet是作为一个宿主程序,由其运行业务Lua文件。 不过我们能轻松的把它作为动态库集成到已有的应用系统里。

    关于协程

    协程是轻量级线程,所以多线程有的问题它也有,只是影响程度不同。 在协程中使用同步API会阻塞当前协程,所以当你的应用程序只有一个协程从外部收取网络消息时,且在消息处理中使用同步API 操作Redis或者Http的话,效率会很低。 这时有两个方案可解决:1 、提供回调形式的异步API, 但这样会使开发概念混乱 ; 2、 在前面说到的情景的消息处理中开启协程,并在其中操作HTTP/Redis,而不是直接在消息处理所在协程中进行操作。 (当然,协程的创建和切换有一定开销,所以~看着办吧 ^-^ )

    例子:

    PingpongServer.lua:

    package.path = "./src/?.lua;./libs/?.lua;"
    
    local TcpService = require "TcpService"
    local AcyncConnect = require "Connect"
    
    local totalRecvNum = 0
    
    function userMain()
    
    	--开启服务器
    	local serverService = TcpService:New()
    	serverService:listen("0.0.0.0", 9999)
    
    	coroutine_start(function()
    		while true do
    			local session = serverService:accept()
    			if session ~= nil then
    				coroutine_start(function ()
    					local strLen = 5		--读取5个字节
    					while true do
    						local packet = session:receive(strLen)
    						if packet ~= nil then
    							totalRecvNum = totalRecvNum + 1
    							session:send(packet)
    						end
    						if session:isClose() then
    							break
    						end
    					end
    				end)
    			end
    		end
    	end)
    
    	coroutine_start(function ()
    			while true do
    				coroutine_sleep(coroutine_running(), 1000)
    				print("total recv :"..totalRecvNum.."/s")
    				totalRecvNum = 0
    			end
    		end)
    end
    
    coroutine_start(function ()
    	userMain()
    end)
    
    while true
    do
    	CoreDD:loop()
    	while coroutine_pengdingnum() > 0
    	do
    		coroutine_schedule()
    	end
    end
    

      PingPongClient.lua:

    package.path = "./src/?.lua;./libs/?.lua;"
    
    local TcpService = require "TcpService"
    local AcyncConnect = require "Connect"
    
    local totalRecvNum = 0
    
    function userMain()
    
    	--开启10个客户端
    	local clientService = TcpService:New()
    	clientService:createService()
    		
    	for i=1,1 do
    		coroutine_start(function ()
    			local session = clientService:connect("127.0.0.1", 9999, 5000)
    
    			if session ~= nil then
    				local str = "hello"
    				local strLen = string.len(str)
    
    				session:send(str)
    				while true do
    				local packet = session:receive(strLen)
    					if packet ~= nil then
    						totalRecvNum = totalRecvNum + 1
    						session:send(packet)
    					end
    
    					if session:isClose() then
    						break
    					end
    				end
    			else
    				print("connect failed")
    			end
    		end)
    	end
    
    	coroutine_start(function ()
    			while true do
    				coroutine_sleep(coroutine_running(), 1000)
    				print("total recv :"..totalRecvNum.."/s")
    				totalRecvNum = 0
    			end
    		end)
    end
    
    coroutine_start(function ()
    	userMain()
    end)
    
    while true
    do
    	CoreDD:loop()
    	while coroutine_pengdingnum() > 0
    	do
    		coroutine_schedule()
    	end
    end
    

      

    Http Server :

    package.path = "./src/?.lua;./libs/?.lua;"
    
    local TcpService = require "TcpService"
    
    local totalRecvNum = 0
    
    function userMain()
    	if true then
    	--开启http服务器
    	local serverService = TcpService:New()
    	serverService:listen("0.0.0.0", 80)
    	coroutine_start(function()
    		while true do
    			local session = serverService:accept()
    			if session ~= nil then
    				coroutine_start(function ()
    
    					--读取报文头
    					local packet = session:receiveUntil("
    ")
    
    					--读取多行头部
    					while true do
    						packet = session:receiveUntil("
    ")
    						if packet ~= nil then
    							if #packet == 0 then
    								--print("recv empty line")
    								break
    							end
    						end
    					end
    
    					local htmlBody = "<html><head><title>This is title</title></head><body>hahaha</body></html>"
    					local response = "HTTP/1.1 200 OK
    Connection: close
    Content-Type: text/html
    Content-Length: "..string.len(htmlBody).."
    
    "..htmlBody
    
    					session:send(response)
    
    					totalRecvNum = totalRecvNum + 1
    				end)
    			end
    		end
    	end)
    
    	coroutine_start(function ()
    			while true do
    				coroutine_sleep(coroutine_running(), 1000)
    				print("total recv :"..totalRecvNum.."/s")
    				totalRecvNum = 0
    			end
    		end)
    end
    
    coroutine_start(function ()
    	userMain()
    end)
    
    while true
    do
    	CoreDD:loop()
    	while coroutine_pengdingnum() > 0
    	do
    		coroutine_schedule()
    	end
    end
    

      

  • 相关阅读:
    Running APP 使用说明
    Android 控件八 WebView 控件
    Android 控件七 ImageView 控件
    Android 控件六 CheckBox 控件
    Android 控件五 RadioButton 控件
    Android 控件四 EditText 控件
    Android 控件三 TextView 控件实现 Button
    Android 控件二 Button
    Android 基础控件演示实例
    Android 控件一 TextView
  • 原文地址:https://www.cnblogs.com/irons/p/5549147.html
Copyright © 2011-2022 走看看