|
Следующая версия
|
Предыдущая версия
|
lm3:ce:t_chat [2020/11/27 19:30] ruben создано |
lm3:ce:t_chat [2020/11/30 15:06] (текущий) ruben |
| ==== Репозитарий ==== | ==== Репозитарий ==== |
| |
| ((https://gitlab.com/lm3.examples/lm3.chat_example lm3.chat_example)) | Файловая структура проекта представлена ниже. |
| | |
| | Необходимые скрипты туториала находятся в репозитарии [[https://gitlab.com/lambda-mu/lm.ver3/lm3.examples/chat|lm3.examples/chat]]. |
| | |
| | Чтобы запустить платформу скачайте бинарный файл и необходимые библиотеки из репозитария [[https://gitlab.com/lambda-mu/lm.ver3/lm3.engine.ce|lm3.engine.ce]] и скопируйте в корень проекта. |
| |
| ==== Исходные данные ==== | ==== Исходные данные ==== |
| Сторону клиента реализует Android-приложение с | Сторону клиента реализует Android-приложение с |
| |
| * запрограммированным модулем связи с платформой | * запрограммированным модулем связи с платформой |
| * протоколом связи, который рассмотрен ниже | * протоколом связи, который рассмотрен ниже |
| |
| ==== Цель проекта ==== | ==== Цель проекта ==== |
| |
| ==== Файловая структура проекта ==== | ==== Файловая структура проекта ==== |
| | |
| | {{ :lm3:ce:chat_struct.png?direct |}} |
| |
| ==== Взаимосвязи ==== | ==== Взаимосвязи ==== |
| | |
| | Объекты основной логической машины: |
| | * TCP-server server: прием и передача данных клиенту |
| | * DataPack packer: распаковка и запаковка данных клиенту |
| | * Auth: авторизация клиента; вызов создания ЛМ; связь клиента с соответствующей ЛМ |
| | * Сlients (наследник LMList): управление ЛМ |
| | |
| | Диаграмма связей: |
| | |
| | {{ :lm3:ce:chat_client.png?direct |}} |
| | |
| | На логических машинах запросы обрабатываются следующим образом: |
| | * команда авторизации DoAuthByName присваивает переменной userName значение и вызывает OnSendAll |
| | * команда сообщения DoSend вызывает OnSendAll, если пользователь авторизирован |
| |
| ==== Скрипты ==== | ==== Скрипты ==== |
| | |
| | **main / start.lua** |
| | |
| | <code lua> |
| | lm3:Log("Starting server") |
| | |
| | lm3:LoadLibrary( {Alias = "sys", FileName = "lm3system"} ) |
| | lm3:Include("main_lib.lua") |
| | |
| | lm3:CreateLObject( { LibAlias = "sys", Type = "TCPServer", Name = "server" } ) |
| | server:SetAttr("SocCount", lmconf.MaxClientCount) |
| | |
| | lm3:CreateLObject( { LibAlias = "sys", Type = "DataPack", Name = "packer" } ) |
| | packer:SetAttr("BufCount", lmconf.MaxClientCount) |
| | |
| | lm3:CreateObject( { Type = "LMList", Name = "clients" } ) |
| | |
| | init_Auth("Auth") |
| | |
| | lm3:AddHandler("OnStart", function(o, ev) |
| | -- проверка конфигурации ЛМ |
| | if clients:DoPrepare(lmconf.BasePath.."client_lm/config.lua") == false then |
| | lm3:Log("client_lm prepare failed") |
| | end |
| | end) |
| | |
| | Auth:AddHandler("OnReply", function(o, ev) |
| | lm3:Log("Auth: OnReply: tag: "..tostring(ev.Tag).." : "..lm3:DataToString(ev.Data)) |
| | end) |
| | |
| | -- связи объектов |
| | server:Connect("OnConnect", "Auth", "DoConnect") |
| | server:Connect("OnDisconnect", "Auth", "DoDisconnect") |
| | server:Connect("OnIncoming", "packer", "DoUnpack") |
| | packer:Connect("OnPack", "server", "DoSend") |
| | |
| | packer:Connect("OnUnpack", "Auth", "DoIncoming") |
| | Auth:Connect("OnReply", "packer", "DoPackTagged") |
| | |
| | Auth:Connect("OnStartClientLM", "clients", "DoStart") |
| | Auth:Connect("OnStopClientLM", "clients", "DoStop") |
| | Auth:Connect("OnClientEvent", "clients", "DoEvent") |
| | clients:Connect("OnEvent", "Auth", "DoClientEvent") |
| | </code> |
| | |
| | **main / main_lib.lua** |
| | |
| | <code lua> |
| | -- объект Auth |
| | -- |
| | function init_Auth(_name) |
| | local obj = lm3:CreateObject( { Type = "Base", Name = _name } ) |
| | |
| | obj.ClientList = {} |
| | for i = 1, lmconf.MaxClientCount do |
| | obj.ClientList[i] = { |
| | isConnected = false, |
| | LMName = "", |
| | } |
| | end |
| | |
| | function obj.TagFromLMName(_name) |
| | return tonumber(_name:sub(5)) |
| | end |
| | |
| | -- подключение нового клиента |
| | -- старт ЛМ |
| | obj:AddInEvent("DoConnect", "int", function(o, ev) |
| | lm3:Log("New client connected: "..tostring(ev)) |
| | obj.ClientList[ev].isConnected = true |
| | obj.ClientList[ev].LMName = "clm_"..tostring(ev) |
| | lm3:Log("Start client LM:") |
| | if obj:OnStartClientLM( { Name = obj.ClientList[ev].LMName } ) == true then |
| | lm3:Log("Start client LM complete.") |
| | else |
| | lm3:Log("ERROR: Start client LM failed.") |
| | obj.ClientList[ev].isConnected = false |
| | end |
| | end) |
| | |
| | -- отключение клиента |
| | -- остановка ЛМ |
| | obj:AddInEvent("DoDisconnect", "int", function(o,ev) |
| | lm3:Log("Client disconnected: "..tostring(ev)) |
| | obj:OnStopClientLM(obj.ClientList[ev].LMName) |
| | obj.ClientList[ev].isConnected = false |
| | end) |
| | |
| | -- распределение данных от клиента |
| | obj:AddInEvent("DoIncoming", "table[Tag:int,Data:table[Command:string,Data:string]]", function(o, ev) |
| | if obj.ClientList[ev.Tag].isConnected ~= true then |
| | lm3:Log("ERROR: Incoming data from not connected client: "..tostring(ev.Tag)) |
| | else |
| | lm3:Log("Incoming data from client with tag: "..tostring(ev.Tag).." : "..lm3:DataToString(ev.Data)) |
| | obj:OnClientEvent({ LMName = obj.ClientList[ev.Tag].LMName, EventName = "OnExtEvent", Data = ev.Data }) |
| | end |
| | end) |
| | |
| | -- обработка данных от ЛМ |
| | obj:AddInEvent("DoClientEvent", "table[LMName:string,EventName:string,Data:table[Command:string,Data:string]]", function(o, ev) |
| | if ev.Data.Command == "OnSendAll" then |
| | for i = 1, lmconf.MaxClientCount do |
| | if obj.ClientList[i].isConnected then |
| | obj:OnReply( { Tag = i, Data = ev.Data } ) |
| | end |
| | end |
| | else |
| | local iClient = obj.TagFromLMName(ev.LMName) |
| | obj:OnReply( { Tag = iClient, Data = ev.Data } ) |
| | end |
| | end) |
| | |
| | -- отправить данные клиенту |
| | obj:AddOutEvent("OnReply", "table[Tag:int,Data:table[Command:string,Data:string]]") |
| | |
| | -- отправить данные в ЛМ |
| | obj:AddOutProc("OnClientEvent", "table[LMName:string,EventName:string,Data:any]", "bool") |
| | |
| | obj:AddOutProc("OnStartClientLM", "table[Name:string]", "bool") |
| | |
| | obj:AddOutProc("OnStopClientLM", "string", "bool") |
| | |
| | return obj |
| | end |
| | </code> |
| | |
| | **main / client_lm / start.lua** |
| | |
| | <code lua> |
| | lm3:LoadLibrary( {Alias = "sys", FileName = "lm3system"} ) |
| | |
| | -- объект Timer для alive сообщение |
| | lm3:CreateObject( { Type = "Timer", Name = "timer" } ) |
| | timer:SetAttr("Interval", 30*1000) |
| | |
| | lm3:AddHandler("OnStart", function(o, ev) |
| | timer:DoEnable(true) |
| | end) |
| | |
| | userName = nil |
| | |
| | -- обработчик ивента с основной логической машины |
| | lm3:AddHandler("OnExtEvent", function(o, ev) |
| | if ev.Command == "DoAuthByName" then |
| | userName = ev.Data |
| | lm3:DoExtEvent( { Command = "OnSendAll", Data = "Member connected: "..userName } ) |
| | elseif ev.Command == "DoSendAll" then |
| | if userName == nil then |
| | lm3:Log("Error: userName == nil") |
| | else |
| | lm3:DoExtEvent( { Command = "OnSendAll", Data = "Member "..userName..": "..ev.Data } ) |
| | end |
| | end |
| | end) |
| | |
| | timer:AddHandler("OnTick", function(o, ev) |
| | --lm3:Log("OnTick: send Alive") |
| | lm3:DoExtEvent( { Command = "Alive", Data = "" } ) |
| | end) |
| | </code> |
| | |
| |
| ==== Логи ==== | ==== Логи ==== |
| | |
| | **[client 1]** |
| | |
| | <code> |
| | -- получение уникального имени |
| | 2020-11-27 19:02:14.044 1940-1940/com.example.lm3_client D/lm3: application: onCreate: uniqueName: 3360d |
| | 2020-11-27 19:02:14.060 1940-1984/com.example.lm3_client D/lm3: application: setNetworkStatus: 2 |
| | -- подключение к серверу |
| | 2020-11-27 19:02:14.060 1940-1984/com.example.lm3_client D/lm3: connect: startServerConnection |
| | 2020-11-27 19:02:14.061 1940-1985/com.example.lm3_client D/lm3: connect: start |
| | 2020-11-27 19:02:14.084 1940-1940/com.example.lm3_client D/lm3: activity: main: OnCreate |
| | 2020-11-27 19:02:14.188 1940-1985/com.example.lm3_client D/lm3: connect: setServerConnection: true |
| | 2020-11-27 19:02:14.189 1940-1985/com.example.lm3_client D/lm3: connect: done |
| | 2020-11-27 19:02:14.189 1940-1985/com.example.lm3_client D/lm3: connect: end |
| | 2020-11-27 19:02:14.189 1940-2027/com.example.lm3_client D/lm3: connect: start listen |
| | 2020-11-27 19:02:14.234 1940-1940/com.example.lm3_client D/lm3: activity: main: onResume |
| | -- авторизация |
| | 2020-11-27 19:02:15.189 1940-2027/com.example.lm3_client D/lm3: listen: DoAuthByName: 3360d |
| | 2020-11-27 19:02:15.190 1940-2027/com.example.lm3_client D/lm3: listen: serverSend |
| | 2020-11-27 19:02:15.252 1940-2027/com.example.lm3_client D/lm3: listen: OnSendAll: Member connected: 3360d |
| | 2020-11-27 19:02:24.392 1940-1940/com.example.lm3_client D/lm3: activity: main: |
| | -- отправка сообщения |
| | button OnClick: message: Hello |
| | 2020-11-27 19:02:24.392 1940-1940/com.example.lm3_client D/lm3: listen: DoSendAll: Hello |
| | 2020-11-27 19:02:24.392 1940-1940/com.example.lm3_client D/lm3: listen: serverSend |
| | 2020-11-27 19:02:24.424 1940-2027/com.example.lm3_client D/lm3: listen: OnSendAll: Member 3360d: Hello |
| | 2020-11-27 19:02:34.153 1940-2027/com.example.lm3_client D/lm3: listen: OnSendAll: Member 65c8c: Hi |
| | </code> |
| | |
| | **[client 2]** |
| | |
| | <code> |
| | -- получение уникального имени |
| | 2020-11-27 19:01:55.396 14523-14523/com.example.lm3_client D/lm3: application: onCreate: uniqueName: 65c8c |
| | 2020-11-27 19:01:55.527 14523-14556/com.example.lm3_client D/lm3: application: setNetworkStatus: 2 |
| | -- подключение к серверу |
| | 2020-11-27 19:01:55.527 14523-14556/com.example.lm3_client D/lm3: connect: startServerConnection |
| | 2020-11-27 19:01:55.529 14523-14557/com.example.lm3_client D/lm3: connect: start |
| | 2020-11-27 19:01:55.544 14523-14557/com.example.lm3_client D/lm3: connect: setServerConnection: true |
| | 2020-11-27 19:01:55.545 14523-14557/com.example.lm3_client D/lm3: connect: done |
| | 2020-11-27 19:01:55.545 14523-14557/com.example.lm3_client D/lm3: connect: end |
| | 2020-11-27 19:01:55.545 14523-14559/com.example.lm3_client D/lm3: connect: start listen |
| | 2020-11-27 19:01:55.573 14523-14523/com.example.lm3_client D/lm3: activity: main: OnCreate |
| | 2020-11-27 19:01:55.716 14523-14523/com.example.lm3_client D/lm3: activity: main: onResume |
| | -- авторизация |
| | 2020-11-27 19:01:56.546 14523-14559/com.example.lm3_client D/lm3: listen: DoAuthByName: 65c8c |
| | 2020-11-27 19:01:56.546 14523-14559/com.example.lm3_client D/lm3: listen: serverSend |
| | 2020-11-27 19:01:56.580 14523-14559/com.example.lm3_client D/lm3: listen: OnSendAll: Member connected: 65c8c |
| | 2020-11-27 19:02:14.398 14523-14559/com.example.lm3_client D/lm3: listen: OnSendAll: Member connected: 3360d |
| | 2020-11-27 19:02:23.602 14523-14559/com.example.lm3_client D/lm3: listen: OnSendAll: Member 3360d: Hello |
| | -- отправка сообщения |
| | 2020-11-27 19:02:33.103 14523-14523/com.example.lm3_client D/lm3: activity: main: button OnClick: message: Hi |
| | 2020-11-27 19:02:33.103 14523-14523/com.example.lm3_client D/lm3: listen: DoSendAll: Hi |
| | 2020-11-27 19:02:33.103 14523-14523/com.example.lm3_client D/lm3: listen: serverSend |
| | 2020-11-27 19:02:33.139 14523-14559/com.example.lm3_client D/lm3: listen: OnSendAll: Member 65c8c: Hi |
| | </code> |
| | |
| | **[server] LM_main.log** |
| | |
| | <code> |
| | [2020-11-27 19:01:30][INFO:LMInit][Start logic machine v3.3(Build:555) ----------------------------------] |
| | [2020-11-27 19:01:30][LUA:LMCore][Starting server] |
| | [2020-11-27 19:01:30][TRACE:LMInit][Create library object: server] |
| | [2020-11-27 19:01:30][TRACE:LMInit][Create library object: packer] |
| | [2020-11-27 19:01:30][TRACE:LMInit][Create object: clients] |
| | [2020-11-27 19:01:30][TRACE:LMInit][Create object: Auth] |
| | [2020-11-27 19:01:30][INFO:LMInit][Initialization complete.] |
| | [2020-11-27 19:01:48][LUA:LMCore][New client connected: 1] |
| | [2020-11-27 19:01:48][LUA:LMCore][Start client LM:] |
| | [2020-11-27 19:01:48][LUA:LMCore][Start client LM complete.] |
| | -- авторизация первого клиента |
| | [2020-11-27 19:01:49][LUA:LMCore][Incoming data from client with tag: 1 : [Table:2] |
| | "Command" = [String] "DoAuthByName" |
| | "Data" = [String] "65c8c"] |
| | [2020-11-27 19:01:49][LUA:LMCore][Auth: OnReply: tag: 1 : [Table:2] |
| | "Command" = [String] "OnSendAll" |
| | "Data" = [String] "Member connected: 65c8c"] |
| | [2020-11-27 19:02:06][LUA:LMCore][New client connected: 2] |
| | [2020-11-27 19:02:06][LUA:LMCore][Start client LM:] |
| | [2020-11-27 19:02:06][LUA:LMCore][Start client LM complete.] |
| | -- авторизация второго клиента |
| | [2020-11-27 19:02:07][LUA:LMCore][Incoming data from client with tag: 2 : [Table:2] |
| | "Command" = [String] "DoAuthByName" |
| | "Data" = [String] "3360d"] |
| | [2020-11-27 19:02:07][LUA:LMCore][Auth: OnReply: tag: 1 : [Table:2] |
| | "Command" = [String] "OnSendAll" |
| | "Data" = [String] "Member connected: 3360d"] |
| | [2020-11-27 19:02:07][LUA:LMCore][Auth: OnReply: tag: 2 : [Table:2] |
| | "Command" = [String] "OnSendAll" |
| | "Data" = [String] "Member connected: 3360d"] |
| | -- сообщение от первого клиента |
| | [2020-11-27 19:02:16][LUA:LMCore][Incoming data from client with tag: 2 : [Table:2] |
| | "Command" = [String] "DoSendAll" |
| | "Data" = [String] "Hello"] |
| | [2020-11-27 19:02:16][LUA:LMCore][Auth: OnReply: tag: 1 : [Table:2] |
| | "Command" = [String] "OnSendAll" |
| | "Data" = [String] "Member 3360d: Hello"] |
| | [2020-11-27 19:02:16][LUA:LMCore][Auth: OnReply: tag: 2 : [Table:2] |
| | "Command" = [String] "OnSendAll" |
| | "Data" = [String] "Member 3360d: Hello"] |
| | [2020-11-27 19:02:18][LUA:LMCore][Auth: OnReply: tag: 1 : [Table:2] |
| | "Command" = [String] "Alive" |
| | "Data" = [String] ""] |
| | -- сообщение от второго клиента |
| | [2020-11-27 19:02:26][LUA:LMCore][Incoming data from client with tag: 1 : [Table:2] |
| | "Command" = [String] "DoSendAll" |
| | "Data" = [String] "Hi"] |
| | [2020-11-27 19:02:26][LUA:LMCore][Auth: OnReply: tag: 1 : [Table:2] |
| | "Command" = [String] "OnSendAll" |
| | "Data" = [String] "Member 65c8c: Hi"] |
| | [2020-11-27 19:02:26][LUA:LMCore][Auth: OnReply: tag: 2 : [Table:2] |
| | "Command" = [String] "OnSendAll" |
| | "Data" = [String] "Member 65c8c: Hi"] |
| | [2020-11-27 19:02:36][LUA:LMCore][Auth: OnReply: tag: 2 : [Table:2] |
| | "Command" = [String] "Alive" |
| | "Data" = [String] ""] |
| | [2020-11-27 19:02:48][LUA:LMCore][Auth: OnReply: tag: 1 : [Table:2] |
| | "Command" = [String] "Alive" |
| | "Data" = [String] ""] |
| | [2020-11-27 19:03:06][INFO:LMCore][Stop logic machine.] |
| | </code> |
| |