├── KafkaGate.ctpr ├── KafkaGate.ctps ├── KafkaGate.exe ├── KafkaGate.ini ├── KafkaGate.lpi ├── KafkaGate.lpr ├── KafkaGate.lps ├── KafkaGate.png ├── KafkaGate.ppr ├── KafkaGate.zip ├── KafkaGate32.lnk ├── KafkaGate64.lnk ├── KafkaPas.zip ├── KafkaPas ├── KafkaPas.exe ├── KafkaPas.ico ├── KafkaPas.lpi ├── KafkaPas.lpr ├── KafkaPas.lps ├── KafkaPas.res ├── consumer.ini ├── formmainkafkatest.lfm ├── formmainkafkatest.pas ├── kafka.pas ├── kafkaclass.pas ├── lib │ ├── i386-win32 │ │ ├── KafkaPas.compiled │ │ ├── KafkaPas.o │ │ ├── KafkaPas.or │ │ ├── KafkaPas.res │ │ ├── formmainkafkatest.lfm │ │ ├── formmainkafkatest.o │ │ ├── formmainkafkatest.ppu │ │ ├── kafka.o │ │ ├── kafka.ppu │ │ ├── kafkaclass.o │ │ ├── kafkaclass.ppu │ │ └── libimpkafka.a │ └── x86_64-win64 │ │ ├── KafkaPas.compiled │ │ ├── KafkaPas.o │ │ ├── KafkaPas.obj │ │ ├── KafkaPas.res │ │ ├── formmainkafkatest.lfm │ │ ├── formmainkafkatest.o │ │ ├── formmainkafkatest.ppu │ │ ├── kafka.o │ │ ├── kafka.ppu │ │ ├── kafkaclass.o │ │ ├── kafkaclass.ppu │ │ └── libimpkafka.a ├── librdkafka.dll ├── librdkafkacpp.dll ├── msvcr120.dll ├── producer.ini ├── rdkafka.pas ├── rdkafka_pas.pas ├── win7-x64 │ └── native │ │ ├── KafkaPas64.exe │ │ ├── consumer.ini │ │ ├── librdkafka.dll │ │ ├── librdkafkacpp.dll │ │ ├── msvcr120.dll │ │ ├── producer.ini │ │ └── zlib.dll ├── win7-x86 │ └── native │ │ ├── KafkaPas32.exe │ │ ├── consumer.ini │ │ ├── librdkafka.dll │ │ ├── librdkafkacpp.dll │ │ ├── msvcr120.dll │ │ ├── producer.ini │ │ └── zlib.dll └── zlib.dll ├── KafkaPasConsumer.png ├── KafkaPasProducer.png ├── README.md ├── config.ini ├── examples ├── CMakeLists.txt ├── Makefile ├── globals.json ├── kafkatest_verifiable_client.cpp ├── rdkafka_consumer_example.c ├── rdkafka_consumer_example.cpp ├── rdkafka_example.c ├── rdkafka_example.cpp ├── rdkafka_performance.c ├── rdkafka_simple_producer.c └── rdkafka_zookeeper_example.c ├── h ├── rdkafka.h └── rdkafkacpp.h ├── heaptrc.trc ├── kafka.pas ├── kafka2zero.pas ├── kafkaclass.pas ├── libgcc_s_dw2-1.dll ├── librdkafka.dll ├── librdkafkacpp.dll ├── libsodium-18.dll ├── libstdc++-6.dll ├── libwinpthread-1.dll ├── libzmq.dll ├── msgqueue ├── kafka.pas ├── kafkaclass.pas ├── nano.pas ├── nanomsgclass.pas ├── old │ └── rdkafka.h ├── rdkafka.h ├── zmq.pas ├── zmqclass.pas └── zmqlogger.pas ├── msvcr120.dll ├── nano.pas ├── nanomsgclass.pas ├── rdkafka.h ├── tv.m3u ├── tv1.m3u ├── win7-x64.zip ├── win7-x64 └── native │ ├── KafkaGate.ini │ ├── KafkaGate64.exe │ ├── config.ini │ ├── libgcc_s_seh-1.dll │ ├── librdkafka.dll │ ├── librdkafkacpp.dll │ ├── libsodium-18.dll │ ├── libstdc++-6.dll │ ├── libwinpthread-1.dll │ ├── libzmq.dll │ ├── msvcr120.dll │ ├── old │ ├── librdkafka.dll │ └── librdkafkacpp.dll │ └── zlib.dll ├── win7-x86.zip ├── win7-x86 └── native │ ├── KafkaGate.ini │ ├── KafkaGate32.exe │ ├── config.ini │ ├── libgcc_s_dw2-1.dll │ ├── librdkafka.dll │ ├── librdkafkacpp.dll │ ├── libsodium-18.dll │ ├── libstdc++-6.dll │ ├── libwinpthread-1.dll │ ├── libzmq.dll │ ├── msvcr120.dll │ ├── old │ ├── librdkafka.dll │ └── librdkafkacpp.dll │ └── zlib.dll ├── zero2kafka.pas ├── zlib.dll ├── zmq.pas ├── zmqclass.pas └── zmqlogger.pas /KafkaGate.ctpr: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | <UseAppBundle Value="False"/> 15 | <ResourceType Value="res"/> 16 | </General> 17 | <BuildModes Count="3"> 18 | <Item1 Name="Default" Default="True"/> 19 | <Item2 Name="Win32"> 20 | <CompilerOptions> 21 | <Version Value="11"/> 22 | <PathDelim Value="\"/> 23 | <Target> 24 | <Filename Value="win7-x86/native/KafkaGate32"/> 25 | </Target> 26 | <SearchPaths> 27 | <IncludeFiles Value="$(ProjOutDir)"/> 28 | <OtherUnitFiles Value="..\FavCommon\msgqueue"/> 29 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 30 | </SearchPaths> 31 | <CodeGeneration> 32 | <TargetCPU Value="i386"/> 33 | <TargetOS Value="win32"/> 34 | <Optimizations> 35 | <OptimizationLevel Value="3"/> 36 | </Optimizations> 37 | </CodeGeneration> 38 | <Linking> 39 | <Debugging> 40 | <GenerateDebugInfo Value="False"/> 41 | </Debugging> 42 | </Linking> 43 | </CompilerOptions> 44 | </Item2> 45 | <Item3 Name="Win64"> 46 | <CompilerOptions> 47 | <Version Value="11"/> 48 | <PathDelim Value="\"/> 49 | <Target> 50 | <Filename Value="win7-x64/native/KafkaGate64"/> 51 | </Target> 52 | <SearchPaths> 53 | <IncludeFiles Value="$(ProjOutDir)"/> 54 | <OtherUnitFiles Value="..\FavCommon\msgqueue"/> 55 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 56 | </SearchPaths> 57 | <CodeGeneration> 58 | <TargetCPU Value="x86_64"/> 59 | <TargetOS Value="win64"/> 60 | <Optimizations> 61 | <OptimizationLevel Value="3"/> 62 | </Optimizations> 63 | </CodeGeneration> 64 | <Linking> 65 | <Debugging> 66 | <GenerateDebugInfo Value="False"/> 67 | </Debugging> 68 | </Linking> 69 | </CompilerOptions> 70 | </Item3> 71 | </BuildModes> 72 | <PublishOptions> 73 | <Version Value="2"/> 74 | </PublishOptions> 75 | <RunParams> 76 | <FormatVersion Value="2"/> 77 | <Modes Count="1"> 78 | <Mode0 Name="default"/> 79 | </Modes> 80 | </RunParams> 81 | <Units Count="5"> 82 | <Unit0> 83 | <Filename Value="KafkaGate.ppr"/> 84 | <IsPartOfProject Value="True"/> 85 | </Unit0> 86 | <Unit1> 87 | <Filename Value="..\FavCommon\msgqueue\zmq.pas"/> 88 | <IsPartOfProject Value="True"/> 89 | </Unit1> 90 | <Unit2> 91 | <Filename Value="..\FavCommon\msgqueue\zmqclass.pas"/> 92 | <IsPartOfProject Value="True"/> 93 | <UnitName Value="ZMQClass"/> 94 | </Unit2> 95 | <Unit3> 96 | <Filename Value="kafka2zero.pas"/> 97 | <IsPartOfProject Value="True"/> 98 | <UnitName Value="Kafka2Zero"/> 99 | </Unit3> 100 | <Unit4> 101 | <Filename Value="zero2kafka.pas"/> 102 | <IsPartOfProject Value="True"/> 103 | <UnitName Value="Zero2Kafka"/> 104 | </Unit4> 105 | </Units> 106 | </ProjectOptions> 107 | <CompilerOptions> 108 | <Version Value="11"/> 109 | <PathDelim Value="\"/> 110 | <Target> 111 | <Filename Value="KafkaGate"/> 112 | </Target> 113 | <SearchPaths> 114 | <IncludeFiles Value="$(ProjOutDir)"/> 115 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 116 | </SearchPaths> 117 | </CompilerOptions> 118 | <Debugging> 119 | <Exceptions Count="5"> 120 | <Item1> 121 | <Name Value="EAbort"/> 122 | </Item1> 123 | <Item2> 124 | <Name Value="ECodetoolError"/> 125 | </Item2> 126 | <Item3> 127 | <Name Value="EFOpenError"/> 128 | </Item3> 129 | <Item4> 130 | <Name Value="EConvertError"/> 131 | </Item4> 132 | <Item5> 133 | <Name Value="E0MQError"/> 134 | </Item5> 135 | </Exceptions> 136 | </Debugging> 137 | </CONFIG> 138 | -------------------------------------------------------------------------------- /KafkaGate.ctps: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectSession> 4 | <PathDelim Value="\"/> 5 | <Version Value="11"/> 6 | <BuildModes Active="Default"/> 7 | <Units Count="10"> 8 | <Unit0> 9 | <Filename Value="KafkaGate.ppr"/> 10 | <IsPartOfProject Value="True"/> 11 | <IsVisibleTab Value="True"/> 12 | <CursorPos X="59" Y="21"/> 13 | <UsageCount Value="64"/> 14 | <Bookmarks Count="1"> 15 | <Item0 X="6" Y="31" ID="8"/> 16 | </Bookmarks> 17 | <Loaded Value="True"/> 18 | </Unit0> 19 | <Unit1> 20 | <Filename Value="..\FavCommon\msgqueue\kafka.pas"/> 21 | <UnitName Value="Kafka"/> 22 | <EditorIndex Value="7"/> 23 | <TopLine Value="529"/> 24 | <CursorPos X="64" Y="546"/> 25 | <UsageCount Value="63"/> 26 | <Loaded Value="True"/> 27 | </Unit1> 28 | <Unit2> 29 | <Filename Value="..\FavCommon\msgqueue\zmq.pas"/> 30 | <IsPartOfProject Value="True"/> 31 | <EditorIndex Value="4"/> 32 | <TopLine Value="145"/> 33 | <CursorPos X="136" Y="165"/> 34 | <UsageCount Value="53"/> 35 | <Loaded Value="True"/> 36 | </Unit2> 37 | <Unit3> 38 | <Filename Value="..\FavCommon\msgqueue\zmqclass.pas"/> 39 | <IsPartOfProject Value="True"/> 40 | <UnitName Value="ZMQClass"/> 41 | <EditorIndex Value="3"/> 42 | <TopLine Value="123"/> 43 | <CursorPos X="157" Y="143"/> 44 | <UsageCount Value="53"/> 45 | <Loaded Value="True"/> 46 | </Unit3> 47 | <Unit4> 48 | <Filename Value="..\FavCommon\msgqueue\kafkaclass.pas"/> 49 | <UnitName Value="KafkaClass"/> 50 | <EditorIndex Value="-1"/> 51 | <TopLine Value="16"/> 52 | <CursorPos Y="13"/> 53 | <UsageCount Value="53"/> 54 | <Bookmarks Count="1"> 55 | <Item0 X="5" Y="278" ID="9"/> 56 | </Bookmarks> 57 | </Unit4> 58 | <Unit5> 59 | <Filename Value="kafka2zero.pas"/> 60 | <IsPartOfProject Value="True"/> 61 | <UnitName Value="Kafka2Zero"/> 62 | <EditorIndex Value="1"/> 63 | <TopLine Value="204"/> 64 | <CursorPos X="116" Y="223"/> 65 | <UsageCount Value="23"/> 66 | <Loaded Value="True"/> 67 | </Unit5> 68 | <Unit6> 69 | <Filename Value="zero2kafka.pas"/> 70 | <IsPartOfProject Value="True"/> 71 | <UnitName Value="Zero2Kafka"/> 72 | <EditorIndex Value="2"/> 73 | <CursorPos Y="32"/> 74 | <UsageCount Value="22"/> 75 | <Loaded Value="True"/> 76 | </Unit6> 77 | <Unit7> 78 | <Filename Value="C:\codetyphon\fpcsrc\rtl\objpas\objpas.pp"/> 79 | <EditorIndex Value="-1"/> 80 | <TopLine Value="18"/> 81 | <CursorPos X="8" Y="33"/> 82 | <UsageCount Value="13"/> 83 | </Unit7> 84 | <Unit8> 85 | <Filename Value="C:\codetyphon\fpcsrc\rtl\inc\systemh.inc"/> 86 | <EditorIndex Value="5"/> 87 | <TopLine Value="744"/> 88 | <CursorPos X="21" Y="760"/> 89 | <UsageCount Value="30"/> 90 | <Loaded Value="True"/> 91 | </Unit8> 92 | <Unit9> 93 | <Filename Value="C:\codetyphon\fpcsrc\rtl\objpas\classes\classesh.inc"/> 94 | <EditorIndex Value="6"/> 95 | <TopLine Value="691"/> 96 | <CursorPos X="14" Y="704"/> 97 | <UsageCount Value="25"/> 98 | <Loaded Value="True"/> 99 | </Unit9> 100 | </Units> 101 | <JumpHistory Count="30" HistoryIndex="29"> 102 | <Position1> 103 | <Filename Value="KafkaGate.ppr"/> 104 | <Caret Line="602" TopLine="571"/> 105 | </Position1> 106 | <Position2> 107 | <Filename Value="KafkaGate.ppr"/> 108 | <Caret Line="603" TopLine="571"/> 109 | </Position2> 110 | <Position3> 111 | <Filename Value="KafkaGate.ppr"/> 112 | <Caret Line="604" TopLine="571"/> 113 | </Position3> 114 | <Position4> 115 | <Filename Value="KafkaGate.ppr"/> 116 | <Caret Line="605" TopLine="571"/> 117 | </Position4> 118 | <Position5> 119 | <Filename Value="KafkaGate.ppr"/> 120 | <Caret Line="606" TopLine="571"/> 121 | </Position5> 122 | <Position6> 123 | <Filename Value="KafkaGate.ppr"/> 124 | <Caret Line="607" TopLine="572"/> 125 | </Position6> 126 | <Position7> 127 | <Filename Value="KafkaGate.ppr"/> 128 | <Caret Line="608" TopLine="573"/> 129 | </Position7> 130 | <Position8> 131 | <Filename Value="KafkaGate.ppr"/> 132 | <Caret Line="591" Column="59" TopLine="574"/> 133 | </Position8> 134 | <Position9> 135 | <Filename Value="zero2kafka.pas"/> 136 | <Caret Line="199" Column="67" TopLine="172"/> 137 | </Position9> 138 | <Position10> 139 | <Filename Value="zero2kafka.pas"/> 140 | <Caret Line="127" TopLine="93"/> 141 | </Position10> 142 | <Position11> 143 | <Filename Value="zero2kafka.pas"/> 144 | <Caret Line="76" Column="5" TopLine="66"/> 145 | </Position11> 146 | <Position12> 147 | <Filename Value="KafkaGate.ppr"/> 148 | <Caret Line="613" TopLine="607"/> 149 | </Position12> 150 | <Position13> 151 | <Filename Value="KafkaGate.ppr"/> 152 | <Caret Line="296" Column="166" TopLine="288"/> 153 | </Position13> 154 | <Position14> 155 | <Filename Value="zero2kafka.pas"/> 156 | <Caret Line="112" Column="61" TopLine="97"/> 157 | </Position14> 158 | <Position15> 159 | <Filename Value="zero2kafka.pas"/> 160 | </Position15> 161 | <Position16> 162 | <Filename Value="zero2kafka.pas"/> 163 | <Caret Line="204" Column="72" TopLine="170"/> 164 | </Position16> 165 | <Position17> 166 | <Filename Value="zero2kafka.pas"/> 167 | <Caret Line="31" Column="11" TopLine="7"/> 168 | </Position17> 169 | <Position18> 170 | <Filename Value="zero2kafka.pas"/> 171 | </Position18> 172 | <Position19> 173 | <Filename Value="zero2kafka.pas"/> 174 | <Caret Line="31" Column="58"/> 175 | </Position19> 176 | <Position20> 177 | <Filename Value="zero2kafka.pas"/> 178 | <Caret Line="116" Column="24" TopLine="82"/> 179 | </Position20> 180 | <Position21> 181 | <Filename Value="zero2kafka.pas"/> 182 | <Caret Line="198" Column="24" TopLine="164"/> 183 | </Position21> 184 | <Position22> 185 | <Filename Value="zero2kafka.pas"/> 186 | <Caret Line="177" Column="16" TopLine="170"/> 187 | </Position22> 188 | <Position23> 189 | <Filename Value="kafka2zero.pas"/> 190 | </Position23> 191 | <Position24> 192 | <Filename Value="kafka2zero.pas"/> 193 | <Caret Line="34"/> 194 | </Position24> 195 | <Position25> 196 | <Filename Value="kafka2zero.pas"/> 197 | </Position25> 198 | <Position26> 199 | <Filename Value="kafka2zero.pas"/> 200 | <Caret Line="33" Column="58"/> 201 | </Position26> 202 | <Position27> 203 | <Filename Value="KafkaGate.ppr"/> 204 | <Caret Line="31" Column="46"/> 205 | </Position27> 206 | <Position28> 207 | <Filename Value="..\FavCommon\msgqueue\zmq.pas"/> 208 | <Caret Line="165" Column="136" TopLine="145"/> 209 | </Position28> 210 | <Position29> 211 | <Filename Value="KafkaGate.ppr"/> 212 | <Caret Line="21" Column="47" TopLine="13"/> 213 | </Position29> 214 | <Position30> 215 | <Filename Value="KafkaGate.ppr"/> 216 | <Caret Line="494" Column="17" TopLine="470"/> 217 | </Position30> 218 | </JumpHistory> 219 | <RunParams> 220 | <FormatVersion Value="2"/> 221 | <Modes Count="0" ActiveMode="default"/> 222 | </RunParams> 223 | </ProjectSession> 224 | </CONFIG> 225 | -------------------------------------------------------------------------------- /KafkaGate.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaGate.exe -------------------------------------------------------------------------------- /KafkaGate.ini: -------------------------------------------------------------------------------- 1 | [kafka_producer] 2 | broker=10.16.14.71:9092 3 | topic=sportfeedxml_2 4 | conf_section=kafka_producer_conf 5 | topic_section=kafka_producer_topic 6 | 7 | [kafka_producer_conf] 8 | message.max.bytes=1500000 9 | socket.keepalive.enable=true 10 | socket.blocking.max.ms=1 11 | queue.buffering.max.messages=2 12 | queue.buffering.max.ms=0 13 | message.send.max.retries=10 14 | retry.backoff.ms=100 15 | compression.codec=none 16 | batch.num.messages=1 17 | delivery.report.only.error=true 18 | socket.nagle.disable=true 19 | 20 | [kafka_producer_topic] 21 | offset.store.method=broker 22 | 23 | 24 | [kafka_consumer] 25 | broker=10.16.14.71:9092 26 | topic=sportfeedxml_2 27 | conf_section=kafka_consumer_conf 28 | topic_section=kafka_consumer_topic 29 | 30 | [kafka_consumer_conf] 31 | group.id=sbofferdispatcher_live17 32 | socket.keepalive.enable=true 33 | socket.blocking.max.ms=1 34 | #socket.blocking.max.ms=1 35 | socket.nagle.disable=true 36 | queued.min.messages=100000 37 | queued.max.messages.kbytes=1000000000 38 | fetch.wait.max.ms=0 39 | #fetch.message.max.bytes=1024 40 | #fetch.message.max.bytes=1000000000 41 | fetch.min.bytes=1 42 | fetch.wait.max.ms=1 43 | fetch.error.backoff.ms=1 44 | message.max.bytes=100000000 45 | auto.commit.interval.ms=5000 46 | enable.auto.offset.store=true 47 | auto.offset.reset=latest 48 | #enable.partition.eof=false 49 | receive.message.max.bytes=1000000000 50 | api.version.request=false 51 | 52 | [kafka_consumer_topic] 53 | offset.store.method=broker 54 | 55 | 56 | [ZERO_SENDER] 57 | address=tcp://127.0.0.1:5558 58 | hwm=200 59 | send_timeout=600 60 | recv_timeout=600 61 | socket_type=PUSH 62 | 63 | [ZERO_RECEIVER] 64 | address=tcp://127.0.0.1:5558 65 | hwm=200 66 | send_timeout=600 67 | recv_timeout=600 68 | socket_type=PULL 69 | -------------------------------------------------------------------------------- /KafkaGate.lpi: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="10"/> 5 | <PathDelim Value="\"/> 6 | <General> 7 | <Flags> 8 | <MainUnitHasCreateFormStatements Value="False"/> 9 | <MainUnitHasTitleStatement Value="False"/> 10 | </Flags> 11 | <SessionStorage Value="InProjectDir"/> 12 | <MainUnit Value="0"/> 13 | <Title Value="KafkaGate"/> 14 | <UseAppBundle Value="False"/> 15 | <ResourceType Value="res"/> 16 | </General> 17 | <BuildModes Count="3"> 18 | <Item1 Name="Default" Default="True"/> 19 | <Item2 Name="Win32"> 20 | <CompilerOptions> 21 | <Version Value="11"/> 22 | <PathDelim Value="\"/> 23 | <Target> 24 | <Filename Value="win7-x86/native/KafkaGate32"/> 25 | </Target> 26 | <SearchPaths> 27 | <IncludeFiles Value="$(ProjOutDir)"/> 28 | <OtherUnitFiles Value="..\FavCommon\msgqueue"/> 29 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 30 | </SearchPaths> 31 | <CodeGeneration> 32 | <TargetCPU Value="i386"/> 33 | <TargetOS Value="win32"/> 34 | <Optimizations> 35 | <OptimizationLevel Value="3"/> 36 | </Optimizations> 37 | </CodeGeneration> 38 | <Linking> 39 | <Debugging> 40 | <GenerateDebugInfo Value="False"/> 41 | </Debugging> 42 | </Linking> 43 | </CompilerOptions> 44 | </Item2> 45 | <Item3 Name="Win64"> 46 | <CompilerOptions> 47 | <Version Value="11"/> 48 | <PathDelim Value="\"/> 49 | <Target> 50 | <Filename Value="win7-x64/native/KafkaGate64"/> 51 | </Target> 52 | <SearchPaths> 53 | <IncludeFiles Value="$(ProjOutDir)"/> 54 | <OtherUnitFiles Value="..\FavCommon\msgqueue"/> 55 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 56 | </SearchPaths> 57 | <CodeGeneration> 58 | <TargetCPU Value="x86_64"/> 59 | <TargetOS Value="win64"/> 60 | <Optimizations> 61 | <OptimizationLevel Value="3"/> 62 | </Optimizations> 63 | </CodeGeneration> 64 | <Linking> 65 | <Debugging> 66 | <GenerateDebugInfo Value="False"/> 67 | </Debugging> 68 | </Linking> 69 | </CompilerOptions> 70 | </Item3> 71 | </BuildModes> 72 | <PublishOptions> 73 | <Version Value="2"/> 74 | </PublishOptions> 75 | <RunParams> 76 | <local> 77 | <FormatVersion Value="1"/> 78 | </local> 79 | </RunParams> 80 | <Units Count="7"> 81 | <Unit0> 82 | <Filename Value="KafkaGate.lpr"/> 83 | <IsPartOfProject Value="True"/> 84 | </Unit0> 85 | <Unit1> 86 | <Filename Value="..\FavCommon\msgqueue\kafka.pas"/> 87 | <IsPartOfProject Value="True"/> 88 | <UnitName Value="Kafka"/> 89 | </Unit1> 90 | <Unit2> 91 | <Filename Value="..\FavCommon\msgqueue\zmq.pas"/> 92 | <IsPartOfProject Value="True"/> 93 | </Unit2> 94 | <Unit3> 95 | <Filename Value="..\FavCommon\msgqueue\zmqclass.pas"/> 96 | <IsPartOfProject Value="True"/> 97 | <UnitName Value="ZMQClass"/> 98 | </Unit3> 99 | <Unit4> 100 | <Filename Value="..\FavCommon\msgqueue\kafkaclass.pas"/> 101 | <IsPartOfProject Value="True"/> 102 | <UnitName Value="KafkaClass"/> 103 | </Unit4> 104 | <Unit5> 105 | <Filename Value="kafka2zero.pas"/> 106 | <IsPartOfProject Value="True"/> 107 | <UnitName Value="Kafka2Zero"/> 108 | </Unit5> 109 | <Unit6> 110 | <Filename Value="zero2kafka.pas"/> 111 | <IsPartOfProject Value="True"/> 112 | <UnitName Value="Zero2Kafka"/> 113 | </Unit6> 114 | </Units> 115 | </ProjectOptions> 116 | <CompilerOptions> 117 | <Version Value="11"/> 118 | <PathDelim Value="\"/> 119 | <Target> 120 | <Filename Value="KafkaGate"/> 121 | </Target> 122 | <SearchPaths> 123 | <IncludeFiles Value="$(ProjOutDir)"/> 124 | <OtherUnitFiles Value="..\FavCommon\msgqueue"/> 125 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 126 | </SearchPaths> 127 | </CompilerOptions> 128 | <Debugging> 129 | <Exceptions Count="5"> 130 | <Item1> 131 | <Name Value="EAbort"/> 132 | </Item1> 133 | <Item2> 134 | <Name Value="ECodetoolError"/> 135 | </Item2> 136 | <Item3> 137 | <Name Value="EFOpenError"/> 138 | </Item3> 139 | <Item4> 140 | <Name Value="EConvertError"/> 141 | </Item4> 142 | <Item5> 143 | <Name Value="E0MQError"/> 144 | </Item5> 145 | </Exceptions> 146 | </Debugging> 147 | </CONFIG> 148 | -------------------------------------------------------------------------------- /KafkaGate.lps: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectSession> 4 | <PathDelim Value="\"/> 5 | <Version Value="10"/> 6 | <BuildModes Active="Default"/> 7 | <Units Count="10"> 8 | <Unit0> 9 | <Filename Value="KafkaGate.lpr"/> 10 | <IsPartOfProject Value="True"/> 11 | <UsageCount Value="64"/> 12 | <Bookmarks Count="1"> 13 | <Item0 X="6" Y="31" ID="8"/> 14 | </Bookmarks> 15 | <Loaded Value="True"/> 16 | </Unit0> 17 | <Unit1> 18 | <Filename Value="..\FavCommon\msgqueue\kafka.pas"/> 19 | <IsPartOfProject Value="True"/> 20 | <UnitName Value="Kafka"/> 21 | <EditorIndex Value="8"/> 22 | <TopLine Value="529"/> 23 | <CursorPos X="64" Y="546"/> 24 | <UsageCount Value="63"/> 25 | <Loaded Value="True"/> 26 | </Unit1> 27 | <Unit2> 28 | <Filename Value="..\FavCommon\msgqueue\zmq.pas"/> 29 | <IsPartOfProject Value="True"/> 30 | <EditorIndex Value="4"/> 31 | <TopLine Value="145"/> 32 | <CursorPos X="22" Y="181"/> 33 | <UsageCount Value="53"/> 34 | <Loaded Value="True"/> 35 | </Unit2> 36 | <Unit3> 37 | <Filename Value="..\FavCommon\msgqueue\zmqclass.pas"/> 38 | <IsPartOfProject Value="True"/> 39 | <UnitName Value="ZMQClass"/> 40 | <EditorIndex Value="3"/> 41 | <TopLine Value="123"/> 42 | <CursorPos X="157" Y="143"/> 43 | <UsageCount Value="53"/> 44 | <Loaded Value="True"/> 45 | </Unit3> 46 | <Unit4> 47 | <Filename Value="..\FavCommon\msgqueue\kafkaclass.pas"/> 48 | <IsPartOfProject Value="True"/> 49 | <UnitName Value="KafkaClass"/> 50 | <EditorIndex Value="5"/> 51 | <TopLine Value="16"/> 52 | <CursorPos Y="13"/> 53 | <UsageCount Value="53"/> 54 | <Bookmarks Count="1"> 55 | <Item0 X="5" Y="278" ID="9"/> 56 | </Bookmarks> 57 | <Loaded Value="True"/> 58 | </Unit4> 59 | <Unit5> 60 | <Filename Value="C:\codetyphon\fpcsrc\rtl\objpas\objpas.pp"/> 61 | <EditorIndex Value="-1"/> 62 | <TopLine Value="18"/> 63 | <CursorPos X="8" Y="33"/> 64 | <UsageCount Value="13"/> 65 | </Unit5> 66 | <Unit6> 67 | <Filename Value="C:\codetyphon\fpcsrc\rtl\inc\systemh.inc"/> 68 | <EditorIndex Value="6"/> 69 | <TopLine Value="744"/> 70 | <CursorPos X="21" Y="760"/> 71 | <UsageCount Value="30"/> 72 | <Loaded Value="True"/> 73 | </Unit6> 74 | <Unit7> 75 | <Filename Value="C:\codetyphon\fpcsrc\rtl\objpas\classes\classesh.inc"/> 76 | <EditorIndex Value="7"/> 77 | <TopLine Value="691"/> 78 | <CursorPos X="14" Y="704"/> 79 | <UsageCount Value="25"/> 80 | <Loaded Value="True"/> 81 | </Unit7> 82 | <Unit8> 83 | <Filename Value="kafka2zero.pas"/> 84 | <IsPartOfProject Value="True"/> 85 | <UnitName Value="Kafka2Zero"/> 86 | <IsVisibleTab Value="True"/> 87 | <EditorIndex Value="1"/> 88 | <TopLine Value="204"/> 89 | <CursorPos X="116" Y="223"/> 90 | <UsageCount Value="23"/> 91 | <Loaded Value="True"/> 92 | </Unit8> 93 | <Unit9> 94 | <Filename Value="zero2kafka.pas"/> 95 | <IsPartOfProject Value="True"/> 96 | <UnitName Value="Zero2Kafka"/> 97 | <EditorIndex Value="2"/> 98 | <CursorPos Y="32"/> 99 | <UsageCount Value="22"/> 100 | <Loaded Value="True"/> 101 | </Unit9> 102 | </Units> 103 | <JumpHistory Count="29" HistoryIndex="28"> 104 | <Position1> 105 | <Filename Value="KafkaGate.lpr"/> 106 | <Caret Line="600" TopLine="571"/> 107 | </Position1> 108 | <Position2> 109 | <Filename Value="KafkaGate.lpr"/> 110 | <Caret Line="601" TopLine="571"/> 111 | </Position2> 112 | <Position3> 113 | <Filename Value="KafkaGate.lpr"/> 114 | <Caret Line="602" TopLine="571"/> 115 | </Position3> 116 | <Position4> 117 | <Filename Value="KafkaGate.lpr"/> 118 | <Caret Line="603" TopLine="571"/> 119 | </Position4> 120 | <Position5> 121 | <Filename Value="KafkaGate.lpr"/> 122 | <Caret Line="604" TopLine="571"/> 123 | </Position5> 124 | <Position6> 125 | <Filename Value="KafkaGate.lpr"/> 126 | <Caret Line="605" TopLine="571"/> 127 | </Position6> 128 | <Position7> 129 | <Filename Value="KafkaGate.lpr"/> 130 | <Caret Line="606" TopLine="571"/> 131 | </Position7> 132 | <Position8> 133 | <Filename Value="KafkaGate.lpr"/> 134 | <Caret Line="607" TopLine="572"/> 135 | </Position8> 136 | <Position9> 137 | <Filename Value="KafkaGate.lpr"/> 138 | <Caret Line="608" TopLine="573"/> 139 | </Position9> 140 | <Position10> 141 | <Filename Value="KafkaGate.lpr"/> 142 | <Caret Line="591" Column="59" TopLine="574"/> 143 | </Position10> 144 | <Position11> 145 | <Filename Value="zero2kafka.pas"/> 146 | <Caret Line="199" Column="67" TopLine="172"/> 147 | </Position11> 148 | <Position12> 149 | <Filename Value="zero2kafka.pas"/> 150 | <Caret Line="127" TopLine="93"/> 151 | </Position12> 152 | <Position13> 153 | <Filename Value="zero2kafka.pas"/> 154 | <Caret Line="76" Column="5" TopLine="66"/> 155 | </Position13> 156 | <Position14> 157 | <Filename Value="KafkaGate.lpr"/> 158 | <Caret Line="613" TopLine="607"/> 159 | </Position14> 160 | <Position15> 161 | <Filename Value="KafkaGate.lpr"/> 162 | <Caret Line="296" Column="166" TopLine="288"/> 163 | </Position15> 164 | <Position16> 165 | <Filename Value="zero2kafka.pas"/> 166 | <Caret Line="112" Column="61" TopLine="97"/> 167 | </Position16> 168 | <Position17> 169 | <Filename Value="zero2kafka.pas"/> 170 | </Position17> 171 | <Position18> 172 | <Filename Value="zero2kafka.pas"/> 173 | <Caret Line="204" Column="72" TopLine="170"/> 174 | </Position18> 175 | <Position19> 176 | <Filename Value="zero2kafka.pas"/> 177 | <Caret Line="31" Column="11" TopLine="7"/> 178 | </Position19> 179 | <Position20> 180 | <Filename Value="zero2kafka.pas"/> 181 | </Position20> 182 | <Position21> 183 | <Filename Value="zero2kafka.pas"/> 184 | <Caret Line="31" Column="58"/> 185 | </Position21> 186 | <Position22> 187 | <Filename Value="zero2kafka.pas"/> 188 | <Caret Line="116" Column="24" TopLine="82"/> 189 | </Position22> 190 | <Position23> 191 | <Filename Value="zero2kafka.pas"/> 192 | <Caret Line="198" Column="24" TopLine="164"/> 193 | </Position23> 194 | <Position24> 195 | <Filename Value="zero2kafka.pas"/> 196 | <Caret Line="177" Column="16" TopLine="170"/> 197 | </Position24> 198 | <Position25> 199 | <Filename Value="kafka2zero.pas"/> 200 | <Caret Line="203" Column="3" TopLine="211"/> 201 | </Position25> 202 | <Position26> 203 | <Filename Value="kafka2zero.pas"/> 204 | </Position26> 205 | <Position27> 206 | <Filename Value="kafka2zero.pas"/> 207 | <Caret Line="34"/> 208 | </Position27> 209 | <Position28> 210 | <Filename Value="kafka2zero.pas"/> 211 | </Position28> 212 | <Position29> 213 | <Filename Value="kafka2zero.pas"/> 214 | <Caret Line="33" Column="58"/> 215 | </Position29> 216 | </JumpHistory> 217 | </ProjectSession> 218 | </CONFIG> 219 | -------------------------------------------------------------------------------- /KafkaGate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaGate.png -------------------------------------------------------------------------------- /KafkaGate.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaGate.zip -------------------------------------------------------------------------------- /KafkaGate32.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaGate32.lnk -------------------------------------------------------------------------------- /KafkaGate64.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaGate64.lnk -------------------------------------------------------------------------------- /KafkaPas.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas.zip -------------------------------------------------------------------------------- /KafkaPas/KafkaPas.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/KafkaPas.exe -------------------------------------------------------------------------------- /KafkaPas/KafkaPas.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/KafkaPas.ico -------------------------------------------------------------------------------- /KafkaPas/KafkaPas.lpi: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectOptions> 4 | <Version Value="10"/> 5 | <PathDelim Value="\"/> 6 | <General> 7 | <SessionStorage Value="InProjectDir"/> 8 | <MainUnit Value="0"/> 9 | <Title Value="KafkaPas"/> 10 | <ResourceType Value="res"/> 11 | <UseXPManifest Value="True"/> 12 | <Icon Value="0"/> 13 | </General> 14 | <BuildModes Count="3"> 15 | <Item1 Name="Default" Default="True"/> 16 | <Item2 Name="ReleaseWin32"> 17 | <CompilerOptions> 18 | <Version Value="11"/> 19 | <PathDelim Value="\"/> 20 | <Target> 21 | <Filename Value="./win7-x86/native/KafkaPas32"/> 22 | </Target> 23 | <SearchPaths> 24 | <IncludeFiles Value="$(ProjOutDir)"/> 25 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 26 | </SearchPaths> 27 | <CodeGeneration> 28 | <TargetCPU Value="i386"/> 29 | <TargetOS Value="win32"/> 30 | <Optimizations> 31 | <OptimizationLevel Value="3"/> 32 | </Optimizations> 33 | </CodeGeneration> 34 | <Linking> 35 | <Debugging> 36 | <GenerateDebugInfo Value="False"/> 37 | </Debugging> 38 | <Options> 39 | <Win32> 40 | <GraphicApplication Value="True"/> 41 | </Win32> 42 | </Options> 43 | </Linking> 44 | </CompilerOptions> 45 | </Item2> 46 | <Item3 Name="ReleaseWin64"> 47 | <CompilerOptions> 48 | <Version Value="11"/> 49 | <PathDelim Value="\"/> 50 | <Target> 51 | <Filename Value="./win7-x64/native/KafkaPas64"/> 52 | </Target> 53 | <SearchPaths> 54 | <IncludeFiles Value="$(ProjOutDir)"/> 55 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 56 | </SearchPaths> 57 | <CodeGeneration> 58 | <TargetCPU Value="x86_64"/> 59 | <TargetOS Value="win64"/> 60 | <Optimizations> 61 | <OptimizationLevel Value="3"/> 62 | </Optimizations> 63 | </CodeGeneration> 64 | <Linking> 65 | <Debugging> 66 | <GenerateDebugInfo Value="False"/> 67 | </Debugging> 68 | <Options> 69 | <Win32> 70 | <GraphicApplication Value="True"/> 71 | </Win32> 72 | </Options> 73 | </Linking> 74 | </CompilerOptions> 75 | </Item3> 76 | </BuildModes> 77 | <PublishOptions> 78 | <Version Value="2"/> 79 | </PublishOptions> 80 | <RunParams> 81 | <local> 82 | <FormatVersion Value="1"/> 83 | </local> 84 | </RunParams> 85 | <RequiredPackages Count="1"> 86 | <Item1> 87 | <PackageName Value="LCL"/> 88 | </Item1> 89 | </RequiredPackages> 90 | <Units Count="4"> 91 | <Unit0> 92 | <Filename Value="KafkaPas.lpr"/> 93 | <IsPartOfProject Value="True"/> 94 | </Unit0> 95 | <Unit1> 96 | <Filename Value="formmainkafkatest.pas"/> 97 | <IsPartOfProject Value="True"/> 98 | <ComponentName Value="frmMainKafkaTest"/> 99 | <HasResources Value="True"/> 100 | <ResourceBaseClass Value="Form"/> 101 | <UnitName Value="FormMainKafkaTest"/> 102 | </Unit1> 103 | <Unit2> 104 | <Filename Value="kafka.pas"/> 105 | <IsPartOfProject Value="True"/> 106 | <UnitName Value="Kafka"/> 107 | </Unit2> 108 | <Unit3> 109 | <Filename Value="kafkaclass.pas"/> 110 | <IsPartOfProject Value="True"/> 111 | <UnitName Value="KafkaClass"/> 112 | </Unit3> 113 | </Units> 114 | </ProjectOptions> 115 | <CompilerOptions> 116 | <Version Value="11"/> 117 | <PathDelim Value="\"/> 118 | <Target> 119 | <Filename Value="KafkaPas"/> 120 | </Target> 121 | <SearchPaths> 122 | <IncludeFiles Value="$(ProjOutDir)"/> 123 | <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> 124 | </SearchPaths> 125 | <Linking> 126 | <Options> 127 | <Win32> 128 | <GraphicApplication Value="True"/> 129 | </Win32> 130 | </Options> 131 | </Linking> 132 | </CompilerOptions> 133 | <Debugging> 134 | <Exceptions Count="3"> 135 | <Item1> 136 | <Name Value="EAbort"/> 137 | </Item1> 138 | <Item2> 139 | <Name Value="ECodetoolError"/> 140 | </Item2> 141 | <Item3> 142 | <Name Value="EFOpenError"/> 143 | </Item3> 144 | </Exceptions> 145 | </Debugging> 146 | </CONFIG> 147 | -------------------------------------------------------------------------------- /KafkaPas/KafkaPas.lpr: -------------------------------------------------------------------------------- 1 | program KafkaPas; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | uses 6 | {$IFDEF UNIX}{$IFDEF UseCThreads} 7 | cthreads, 8 | {$ENDIF}{$ENDIF} 9 | Interfaces, // this includes the LCL widgetset 10 | Forms, FormMainKafkaTest; 11 | 12 | {$R *.res} 13 | 14 | begin 15 | RequireDerivedFormResource := True; 16 | Application.Initialize; 17 | Application.CreateForm(TfrmMainKafkaTest, frmMainKafkaTest); 18 | Application.Run; 19 | end. 20 | 21 | -------------------------------------------------------------------------------- /KafkaPas/KafkaPas.lps: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <ProjectSession> 4 | <PathDelim Value="\"/> 5 | <Version Value="10"/> 6 | <BuildModes Active="ReleaseWin64"/> 7 | <Units Count="11"> 8 | <Unit0> 9 | <Filename Value="KafkaPas.lpr"/> 10 | <IsPartOfProject Value="True"/> 11 | <EditorIndex Value="4"/> 12 | <CursorPos X="135" Y="13"/> 13 | <UsageCount Value="48"/> 14 | <Loaded Value="True"/> 15 | </Unit0> 16 | <Unit1> 17 | <Filename Value="formmainkafkatest.pas"/> 18 | <IsPartOfProject Value="True"/> 19 | <ComponentName Value="frmMainKafkaTest"/> 20 | <HasResources Value="True"/> 21 | <ResourceBaseClass Value="Form"/> 22 | <UnitName Value="FormMainKafkaTest"/> 23 | <IsVisibleTab Value="True"/> 24 | <TopLine Value="122"/> 25 | <CursorPos X="68" Y="136"/> 26 | <UsageCount Value="48"/> 27 | <Loaded Value="True"/> 28 | <LoadedDesigner Value="True"/> 29 | </Unit1> 30 | <Unit2> 31 | <Filename Value="kafka.pas"/> 32 | <IsPartOfProject Value="True"/> 33 | <UnitName Value="Kafka"/> 34 | <EditorIndex Value="3"/> 35 | <TopLine Value="364"/> 36 | <CursorPos X="3" Y="385"/> 37 | <UsageCount Value="25"/> 38 | <Loaded Value="True"/> 39 | </Unit2> 40 | <Unit3> 41 | <Filename Value="kafkaclass.pas"/> 42 | <IsPartOfProject Value="True"/> 43 | <UnitName Value="KafkaClass"/> 44 | <EditorIndex Value="2"/> 45 | <TopLine Value="430"/> 46 | <CursorPos X="21" Y="451"/> 47 | <UsageCount Value="25"/> 48 | <Loaded Value="True"/> 49 | </Unit3> 50 | <Unit4> 51 | <Filename Value="rdkafka_pas.pas"/> 52 | <EditorIndex Value="5"/> 53 | <CursorPos X="136" Y="9"/> 54 | <UsageCount Value="45"/> 55 | <Bookmarks Count="2"> 56 | <Item0 X="38" Y="382" ID="8"/> 57 | <Item1 Y="518" ID="9"/> 58 | </Bookmarks> 59 | <Loaded Value="True"/> 60 | </Unit4> 61 | <Unit5> 62 | <Filename Value="rdkafka.pas"/> 63 | <EditorIndex Value="10"/> 64 | <TopLine Value="3073"/> 65 | <CursorPos Y="3099"/> 66 | <UsageCount Value="25"/> 67 | <Loaded Value="True"/> 68 | </Unit5> 69 | <Unit6> 70 | <Filename Value="C:\codetyphon\fpcsrc\rtl\win\sysosh.inc"/> 71 | <EditorIndex Value="9"/> 72 | <TopLine Value="8"/> 73 | <CursorPos X="3" Y="23"/> 74 | <UsageCount Value="25"/> 75 | <Loaded Value="True"/> 76 | </Unit6> 77 | <Unit7> 78 | <Filename Value="C:\codetyphon\fpcsrc\rtl\objpas\sysutils\sysutilh.inc"/> 79 | <EditorIndex Value="8"/> 80 | <TopLine Value="48"/> 81 | <CursorPos X="4" Y="63"/> 82 | <UsageCount Value="25"/> 83 | <Loaded Value="True"/> 84 | </Unit7> 85 | <Unit8> 86 | <Filename Value="C:\codetyphon\fpcsrc\packages\rtl-extra\src\win\winsock.pp"/> 87 | <EditorIndex Value="7"/> 88 | <TopLine Value="31"/> 89 | <UsageCount Value="20"/> 90 | <Loaded Value="True"/> 91 | </Unit8> 92 | <Unit9> 93 | <Filename Value="C:\codetyphon\fpcsrc\rtl\inc\ctypes.pp"/> 94 | <EditorIndex Value="6"/> 95 | <UsageCount Value="20"/> 96 | <Loaded Value="True"/> 97 | </Unit9> 98 | <Unit10> 99 | <Filename Value="C:\codetyphon\typhon\lcl\forms.pp"/> 100 | <UnitName Value="Forms"/> 101 | <EditorIndex Value="1"/> 102 | <TopLine Value="1454"/> 103 | <CursorPos X="15" Y="1473"/> 104 | <UsageCount Value="11"/> 105 | <Loaded Value="True"/> 106 | </Unit10> 107 | </Units> 108 | <JumpHistory Count="29" HistoryIndex="28"> 109 | <Position1> 110 | <Filename Value="kafkaclass.pas"/> 111 | <Caret Line="66" Column="27" TopLine="45"/> 112 | </Position1> 113 | <Position2> 114 | <Filename Value="kafkaclass.pas"/> 115 | <Caret Line="685" TopLine="677"/> 116 | </Position2> 117 | <Position3> 118 | <Filename Value="kafkaclass.pas"/> 119 | <Caret Line="120" Column="56" TopLine="99"/> 120 | </Position3> 121 | <Position4> 122 | <Filename Value="kafkaclass.pas"/> 123 | <Caret Line="849" Column="32" TopLine="833"/> 124 | </Position4> 125 | <Position5> 126 | <Filename Value="kafkaclass.pas"/> 127 | <Caret Line="801" Column="18" TopLine="771"/> 128 | </Position5> 129 | <Position6> 130 | <Filename Value="formmainkafkatest.pas"/> 131 | <Caret Line="153" Column="122" TopLine="119"/> 132 | </Position6> 133 | <Position7> 134 | <Filename Value="kafkaclass.pas"/> 135 | <Caret Line="701" Column="50" TopLine="678"/> 136 | </Position7> 137 | <Position8> 138 | <Filename Value="formmainkafkatest.pas"/> 139 | <Caret Line="153" Column="111" TopLine="119"/> 140 | </Position8> 141 | <Position9> 142 | <Filename Value="formmainkafkatest.pas"/> 143 | <Caret Line="50" Column="34" TopLine="29"/> 144 | </Position9> 145 | <Position10> 146 | <Filename Value="formmainkafkatest.pas"/> 147 | <Caret Line="138" Column="146" TopLine="108"/> 148 | </Position10> 149 | <Position11> 150 | <Filename Value="formmainkafkatest.pas"/> 151 | <Caret Line="142" Column="124" TopLine="128"/> 152 | </Position11> 153 | <Position12> 154 | <Filename Value="formmainkafkatest.pas"/> 155 | <Caret Line="39" Column="15" TopLine="22"/> 156 | </Position12> 157 | <Position13> 158 | <Filename Value="formmainkafkatest.pas"/> 159 | <Caret Line="56" Column="28" TopLine="20"/> 160 | </Position13> 161 | <Position14> 162 | <Filename Value="formmainkafkatest.pas"/> 163 | <Caret Line="229" TopLine="139"/> 164 | </Position14> 165 | <Position15> 166 | <Filename Value="formmainkafkatest.pas"/> 167 | <Caret Line="108" Column="37" TopLine="104"/> 168 | </Position15> 169 | <Position16> 170 | <Filename Value="formmainkafkatest.pas"/> 171 | <Caret Line="111" Column="41" TopLine="87"/> 172 | </Position16> 173 | <Position17> 174 | <Filename Value="formmainkafkatest.pas"/> 175 | <Caret Line="114" Column="81" TopLine="87"/> 176 | </Position17> 177 | <Position18> 178 | <Filename Value="formmainkafkatest.pas"/> 179 | <Caret Line="227" Column="44" TopLine="200"/> 180 | </Position18> 181 | <Position19> 182 | <Filename Value="formmainkafkatest.pas"/> 183 | <Caret Line="204" Column="14" TopLine="188"/> 184 | </Position19> 185 | <Position20> 186 | <Filename Value="formmainkafkatest.pas"/> 187 | <Caret Line="241" Column="30" TopLine="208"/> 188 | </Position20> 189 | <Position21> 190 | <Filename Value="formmainkafkatest.pas"/> 191 | <Caret Line="231" Column="37" TopLine="212"/> 192 | </Position21> 193 | <Position22> 194 | <Filename Value="kafkaclass.pas"/> 195 | <Caret Line="928" Column="3" TopLine="920"/> 196 | </Position22> 197 | <Position23> 198 | <Filename Value="kafka.pas"/> 199 | <Caret Line="385" Column="3" TopLine="364"/> 200 | </Position23> 201 | <Position24> 202 | <Filename Value="formmainkafkatest.pas"/> 203 | <Caret Line="231" Column="32" TopLine="210"/> 204 | </Position24> 205 | <Position25> 206 | <Filename Value="formmainkafkatest.pas"/> 207 | <Caret Line="236" Column="141" TopLine="213"/> 208 | </Position25> 209 | <Position26> 210 | <Filename Value="formmainkafkatest.pas"/> 211 | </Position26> 212 | <Position27> 213 | <Filename Value="formmainkafkatest.pas"/> 214 | <Caret Line="57" Column="23" TopLine="23"/> 215 | </Position27> 216 | <Position28> 217 | <Filename Value="KafkaPas.lpr"/> 218 | <Caret Line="13" Column="135"/> 219 | </Position28> 220 | <Position29> 221 | <Filename Value="formmainkafkatest.pas"/> 222 | <Caret Line="226" Column="32" TopLine="163"/> 223 | </Position29> 224 | </JumpHistory> 225 | </ProjectSession> 226 | </CONFIG> 227 | -------------------------------------------------------------------------------- /KafkaPas/KafkaPas.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/KafkaPas.res -------------------------------------------------------------------------------- /KafkaPas/consumer.ini: -------------------------------------------------------------------------------- 1 | [config] 2 | broker=10.16.14.71:9092 3 | topic=sportfeedxml_2 4 | conf_section=consumer_conf 5 | topic_section=consumer_topic 6 | 7 | [consumer_conf] 8 | group.id=sbofferdispatcher_live17 9 | socket.keepalive.enable=true 10 | socket.blocking.max.ms=1 11 | #socket.blocking.max.ms=1 12 | socket.nagle.disable=true 13 | queued.min.messages=100000 14 | queued.max.messages.kbytes=1000000000 15 | fetch.wait.max.ms=0 16 | #fetch.message.max.bytes=1024 17 | #fetch.message.max.bytes=1000000000 18 | fetch.min.bytes=1 19 | fetch.wait.max.ms=1 20 | fetch.error.backoff.ms=1 21 | message.max.bytes=100000000 22 | auto.commit.interval.ms=5000 23 | enable.auto.offset.store=true 24 | auto.offset.reset=latest 25 | #enable.partition.eof=false 26 | receive.message.max.bytes=1000000000 27 | api.version.request=false 28 | 29 | [consumer_topic] 30 | offset.store.method=broker 31 | -------------------------------------------------------------------------------- /KafkaPas/formmainkafkatest.lfm: -------------------------------------------------------------------------------- 1 | object frmMainKafkaTest: TfrmMainKafkaTest 2 | Left = 590 3 | Height = 768 4 | Top = 245 5 | Width = 1024 6 | Caption = 'Kafka Test' 7 | ClientHeight = 768 8 | ClientWidth = 1024 9 | Font.Name = 'Tahoma' 10 | OnCreate = FormCreate 11 | LCLVersion = '6.0' 12 | object pTop: TPanel 13 | Left = 0 14 | Height = 34 15 | Top = 0 16 | Width = 1024 17 | Align = alTop 18 | Caption = 'Kafka Read and Write Test Program' 19 | Font.Height = 24 20 | ParentFont = False 21 | TabOrder = 0 22 | end 23 | object pLeft: TPanel 24 | Left = 0 25 | Height = 630 26 | Top = 34 27 | Width = 278 28 | Align = alLeft 29 | ClientHeight = 630 30 | ClientWidth = 278 31 | TabOrder = 1 32 | object mParams: TMemo 33 | Left = 1 34 | Height = 602 35 | Top = 27 36 | Width = 276 37 | Align = alClient 38 | Font.Height = 14 39 | Font.Name = 'Tahoma' 40 | ParentFont = False 41 | TabOrder = 0 42 | end 43 | object pLeftCaption: TPanel 44 | Left = 1 45 | Height = 26 46 | Top = 1 47 | Width = 276 48 | Align = alTop 49 | Caption = 'Params' 50 | TabOrder = 1 51 | end 52 | end 53 | object pCenter: TPanel 54 | Left = 283 55 | Height = 630 56 | Top = 34 57 | Width = 741 58 | Align = alClient 59 | ClientHeight = 630 60 | ClientWidth = 741 61 | TabOrder = 2 62 | object mResult: TMemo 63 | Left = 1 64 | Height = 602 65 | Top = 27 66 | Width = 739 67 | Align = alClient 68 | TabOrder = 0 69 | end 70 | object pCenterCaption: TPanel 71 | Left = 1 72 | Height = 26 73 | Top = 1 74 | Width = 739 75 | Align = alTop 76 | Caption = 'Results' 77 | TabOrder = 1 78 | end 79 | end 80 | object pBottom: TPanel 81 | Left = 0 82 | Height = 104 83 | Top = 664 84 | Width = 1024 85 | Align = alBottom 86 | ClientHeight = 104 87 | ClientWidth = 1024 88 | TabOrder = 3 89 | object btnStart: TButton 90 | Left = 8 91 | Height = 88 92 | Top = 8 93 | Width = 150 94 | Caption = 'Start' 95 | OnClick = btnStartClick 96 | TabOrder = 0 97 | end 98 | object btnStop: TButton 99 | Left = 862 100 | Height = 88 101 | Top = 8 102 | Width = 150 103 | Anchors = [akTop, akRight] 104 | Caption = 'Stop' 105 | OnClick = btnStopClick 106 | TabOrder = 1 107 | end 108 | object edBroker: TEdit 109 | Left = 400 110 | Height = 27 111 | Hint = 'Broker Address' 112 | Top = 8 113 | Width = 226 114 | ReadOnly = True 115 | TabOrder = 2 116 | end 117 | object edTopic: TEdit 118 | Left = 400 119 | Height = 27 120 | Hint = 'Topic Name' 121 | Top = 36 122 | Width = 226 123 | ReadOnly = True 124 | TabOrder = 3 125 | end 126 | object edTopicSection: TEdit 127 | Left = 632 128 | Height = 27 129 | Hint = 'Topic Section' 130 | Top = 36 131 | Width = 226 132 | ReadOnly = True 133 | TabOrder = 4 134 | end 135 | object lBrokerCaption: TLabel 136 | Left = 288 137 | Height = 19 138 | Top = 16 139 | Width = 100 140 | AutoSize = False 141 | Caption = 'Broker' 142 | ParentColor = False 143 | end 144 | object lTopicCaption: TLabel 145 | Left = 288 146 | Height = 19 147 | Top = 44 148 | Width = 100 149 | AutoSize = False 150 | Caption = 'Topic' 151 | ParentColor = False 152 | end 153 | object lConfCaption: TLabel 154 | Left = 288 155 | Height = 19 156 | Top = 72 157 | Width = 100 158 | AutoSize = False 159 | Caption = 'Conf' 160 | ParentColor = False 161 | end 162 | object edConfSection: TEdit 163 | Left = 400 164 | Height = 27 165 | Hint = 'Config Section' 166 | Top = 64 167 | Width = 226 168 | ReadOnly = True 169 | TabOrder = 5 170 | end 171 | object rbConsumer: TRadioButton 172 | Left = 174 173 | Height = 23 174 | Top = 24 175 | Width = 92 176 | Caption = 'Consumer' 177 | Checked = True 178 | OnChange = rbConsumerChange 179 | TabOrder = 7 180 | TabStop = True 181 | end 182 | object rbProducer: TRadioButton 183 | Left = 174 184 | Height = 23 185 | Top = 60 186 | Width = 83 187 | Caption = 'Producer' 188 | TabOrder = 6 189 | end 190 | object cbMaxMessageSize: TComboBox 191 | Left = 632 192 | Height = 27 193 | Top = 8 194 | Width = 226 195 | ItemHeight = 19 196 | ItemIndex = 1 197 | Items.Strings = ( 198 | '0 - Whole Message' 199 | '1024 - Trim to 1K Message' 200 | '2048 - Trim to 2K Message' 201 | ) 202 | Style = csDropDownList 203 | TabOrder = 8 204 | Text = '1024 - Trim to 1K Message' 205 | end 206 | object cbSendPause: TComboBox 207 | Left = 632 208 | Height = 27 209 | Top = 64 210 | Width = 226 211 | ItemHeight = 19 212 | ItemIndex = 1 213 | Items.Strings = ( 214 | '10ms send pause' 215 | '100ms send pause' 216 | '200ms send pause' 217 | '300ms send pause' 218 | '400ms send pause' 219 | '500ms send pause' 220 | '600ms send pause' 221 | '700ms send pause' 222 | '800ms send pause' 223 | '900ms send pause' 224 | '1000ms send pause' 225 | '' 226 | ) 227 | Style = csDropDownList 228 | TabOrder = 9 229 | Text = '100ms send pause' 230 | end 231 | end 232 | object splLeftCenter: TSplitter 233 | Left = 278 234 | Height = 630 235 | Top = 34 236 | Width = 5 237 | end 238 | end 239 | -------------------------------------------------------------------------------- /KafkaPas/formmainkafkatest.pas: -------------------------------------------------------------------------------- 1 | unit FormMainKafkaTest; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | interface 6 | 7 | uses 8 | Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, 9 | ExtCtrls, Kafka, KafkaClass, IniFiles; 10 | 11 | type 12 | 13 | { TfrmMainKafkaTest } 14 | 15 | TfrmMainKafkaTest = class(TForm) 16 | btnStart: TButton; 17 | btnStop: TButton; 18 | cbMaxMessageSize: TComboBox; 19 | cbSendPause: TComboBox; 20 | edConfSection: TEdit; 21 | edTopicSection: TEdit; 22 | edBroker: TEdit; 23 | edTopic: TEdit; 24 | lBrokerCaption: TLabel; 25 | lTopicCaption: TLabel; 26 | lConfCaption: TLabel; 27 | mResult: TMemo; 28 | mParams: TMemo; 29 | pLeftCaption: TPanel; 30 | pBottom: TPanel; 31 | pCenter: TPanel; 32 | pCenterCaption: TPanel; 33 | pTop: TPanel; 34 | pLeft: TPanel; 35 | rbConsumer: TRadioButton; 36 | rbProducer: TRadioButton; 37 | splLeftCenter: TSplitter; 38 | procedure btnStartClick(Sender: TObject); 39 | procedure btnStopClick(Sender: TObject); 40 | procedure FormCreate(Sender: TObject); 41 | procedure rbConsumerChange(Sender: TObject); 42 | private 43 | 44 | public 45 | _KafkaConsumer: TKafkaConsumer; 46 | _KafkaProducer: TKafkaProducer; 47 | 48 | _KafkaSetup : TKafkaSetup; 49 | _MessageCount : Integer; 50 | 51 | procedure OnKafkaMessageReceived (InMessage: String; InKey: String; OutMsg: Prd_kafka_message_t); 52 | procedure OnKafkaMessageEOF(InMessage: String); 53 | procedure OnKafkaMessageErr(InError: String); 54 | procedure OnKafkaTick(InHow: String); 55 | 56 | procedure StartConsumer; 57 | procedure StartProducer; 58 | end; 59 | 60 | var 61 | frmMainKafkaTest: TfrmMainKafkaTest; 62 | 63 | implementation 64 | 65 | {$R *.lfm} 66 | 67 | { TfrmMainKafkaTest } 68 | 69 | procedure TfrmMainKafkaTest.btnStartClick(Sender: TObject); 70 | begin 71 | if rbConsumer.Checked then begin 72 | StartConsumer; 73 | end 74 | else begin 75 | StartProducer; 76 | end; 77 | end; 78 | 79 | procedure TfrmMainKafkaTest.btnStopClick(Sender: TObject); 80 | begin 81 | if _KafkaConsumer <> nil then begin 82 | _KafkaConsumer._BStop := True; 83 | end; 84 | if _KafkaProducer <> nil then begin 85 | _KafkaProducer._BStop := True; 86 | end; 87 | end; 88 | 89 | procedure TfrmMainKafkaTest.FormCreate(Sender: TObject); 90 | begin 91 | mResult.Lines.Add('*************************************************************'); 92 | mResult.Lines.Add('Testing library version...'); 93 | mResult.Lines.add('Kafka.rd_kafka_version: ' + IntToStr(Kafka.rd_kafka_version)); 94 | mResult.Lines.add('Kafka.rd_kafka_version_str: ' + String(Kafka.rd_kafka_version_str)); 95 | mResult.Lines.add('Kafka.rd_kafka_get_debug_contexts: ' + String(Kafka.rd_kafka_get_debug_contexts)); 96 | mResult.Lines.add('Kafka.rd_kafka_err2str(RD_KAFKA_RESP_ERR__QUEUE_FULL): ' + String(Kafka.rd_kafka_err2str(RD_KAFKA_RESP_ERR__QUEUE_FULL))); 97 | mResult.Lines.add('Kafka.rd_kafka_err2name(RD_KAFKA_RESP_ERR__QUEUE_FULL): ' + String(Kafka.rd_kafka_err2name(RD_KAFKA_RESP_ERR__QUEUE_FULL))); 98 | mResult.Lines.add('Kafka.rd_kafka_last_error: ' + IntToStr(Kafka.rd_kafka_last_error)); 99 | mResult.Lines.add('Kafka.rd_kafka_errno2err: ' + IntToStr(Kafka.rd_kafka_errno2err(Kafka.rd_kafka_last_error))); 100 | mResult.Lines.Add('End of Testing library version...'); 101 | mResult.Lines.Add('*************************************************************'); 102 | 103 | // mResult.Lines.Add('Reading configuration'); 104 | mParams.Lines.LoadFromFile('.\consumer.ini'); 105 | rbConsumerChange(rbConsumer); 106 | end; 107 | 108 | procedure TfrmMainKafkaTest.rbConsumerChange(Sender: TObject); 109 | begin 110 | if rbConsumer.Checked then begin 111 | pTop.Color := clMoneyGreen; 112 | mParams.Lines.LoadFromFile('.\consumer.ini'); 113 | pLeftCaption.Caption := 'Params: .\consumer.ini'; 114 | end 115 | else begin 116 | pTop.Color := clSkyBlue; 117 | mParams.Lines.LoadFromFile('.\producer.ini'); 118 | pLeftCaption.Caption := 'Params: .\producer.ini'; 119 | end; 120 | end; 121 | 122 | procedure TfrmMainKafkaTest.OnKafkaMessageReceived(InMessage: String; 123 | InKey: String; OutMsg: Prd_kafka_message_t); 124 | begin 125 | Inc(_MessageCount); 126 | mResult.Clear; 127 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + IntToStr(_MessageCount)); 128 | mResult.Lines.Add(InMessage); 129 | end; 130 | 131 | procedure TfrmMainKafkaTest.OnKafkaMessageEOF(InMessage: String); 132 | begin 133 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' Received EOF'); 134 | end; 135 | 136 | procedure TfrmMainKafkaTest.OnKafkaMessageErr(InError: String); 137 | begin 138 | mResult.Clear; 139 | mResult.Lines.Add('ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR ERR'); 140 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + IntToStr(_MessageCount)); 141 | mResult.Lines.Add(InError); 142 | end; 143 | 144 | procedure TfrmMainKafkaTest.OnKafkaTick(InHow: String); 145 | begin 146 | if InHow <> 'WAITFORMESSAGES-POLL' then begin 147 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + InHow); 148 | end; 149 | Application.ProcessMessages; 150 | end; 151 | 152 | procedure TfrmMainKafkaTest.StartConsumer; 153 | var MyFileName: String; 154 | begin 155 | _MessageCount := 0; 156 | MyFileName := '.\consumer.ini'; 157 | 158 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'ReadVariables from ' + MyFileName); 159 | Application.ProcessMessages; 160 | 161 | // Save variables from mParams 162 | if Trim(mParams.Text) <> '' then begin 163 | mParams.Lines.SaveToFile(MyFileName); 164 | end; 165 | 166 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'Create consumer'); 167 | Application.ProcessMessages; 168 | 169 | // Create consumer 170 | _KafkaConsumer := TKafkaConsumer.Create(False); 171 | 172 | // call function which will read configuration 173 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'Read Configuration'); 174 | Application.ProcessMessages; 175 | KafkaReadConfiguration(MyFileName, 'config', _KafkaSetup); 176 | 177 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'Show Variables'); 178 | Application.ProcessMessages; 179 | edBroker.Text := _KafkaSetup.broker; 180 | edTopic.Text := _KafkaSetup.topic; 181 | edConfSection.Text := _KafkaSetup.conf_section; 182 | edTopicSection.Text := _KafkaSetup.topic_section; 183 | 184 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'Start Consumer'); 185 | Application.ProcessMessages; 186 | _KafkaConsumer.StartConsumer(_KafkaSetup, 187 | @OnKafkaMessageReceived, 188 | @OnKafkaMessageEOF, 189 | @OnKafkaMessageErr, 190 | @OnKafkaTick, 191 | cbMaxMessageSize.ItemIndex * 1 * 1024); 192 | 193 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'Free Consumer'); 194 | Application.ProcessMessages; 195 | if _KafkaConsumer <> nil then FreeAndNil(_KafkaConsumer); 196 | end; 197 | 198 | procedure TfrmMainKafkaTest.StartProducer; 199 | var MyFileName: String; 200 | My_dr_msg_cb: TProc_dr_msg_cb; 201 | MyKey, MyMessage: String; 202 | F: Integer; 203 | begin 204 | _MessageCount := 0; 205 | MyFileName := '.\producer.ini'; 206 | 207 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'ReadVariables from ' + MyFileName); 208 | Application.ProcessMessages; 209 | 210 | // Save variables from mParams 211 | if Trim(mParams.Text) <> '' then begin 212 | mParams.Lines.SaveToFile(MyFileName); 213 | end; 214 | 215 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'Create procucer'); 216 | Application.ProcessMessages; 217 | 218 | // Create producer 219 | _KafkaProducer := TKafkaProducer.Create(False); 220 | 221 | // call function which will read configuration 222 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'Read Configuration'); 223 | Application.ProcessMessages; 224 | KafkaReadConfiguration(MyFileName, 'config', _KafkaSetup); 225 | 226 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'Show Variables'); 227 | Application.ProcessMessages; 228 | edBroker.Text := _KafkaSetup.broker; 229 | edTopic.Text := _KafkaSetup.topic; 230 | edConfSection.Text := _KafkaSetup.conf_section; 231 | edTopicSection.Text := _KafkaSetup.topic_section; 232 | 233 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'Start Consumer'); 234 | _KafkaProducer.StartProducer(_KafkaSetup, 235 | My_dr_msg_cb); 236 | 237 | F := 0; 238 | while true do begin 239 | if _KafkaProducer._BStop then Break; 240 | Inc(F); 241 | MyKey := IntToStr(F mod 100); 242 | MyMessage := '<xml no="' + IntToStr(F) + '">' + FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now) + '</xml>'; 243 | _KafkaProducer.ProduceMessage(MyKey, MyMessage); 244 | mResult.Lines.Add(MyMessage); 245 | if ((F mod 1000) = 0) then mResult.Clear; 246 | Application.ProcessMessages; 247 | if cbSendPause.ItemIndex = 0 then begin 248 | Sleep(10); 249 | end 250 | else begin 251 | Sleep(cbSendPause.ItemIndex * 100); 252 | end; 253 | end; 254 | 255 | mResult.Lines.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz: ', Now) + ' ' + 'Free Producer'); 256 | Application.ProcessMessages; 257 | if _KafkaProducer <> nil then FreeAndNil(_KafkaProducer); 258 | end; 259 | 260 | end. 261 | 262 | -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/KafkaPas.compiled: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <Compiler Value="C:\codetyphon\fpc\fpc32\bin\i386-win32\fpc.exe" Date="1246330200"/> 4 | <Params Value=" -Twin32 -Pi386 -MObjFPC -Scghi -O3 -WG -l -vewnhibq -FiG:\sb\src\branch0650\KafkaGate\KafkaPas\lib\i386-win32 -FuC:\codetyphon\typhon\lcl\units\i386-win32\win32 -FuC:\codetyphon\typhon\lcl\units\i386-win32 -FuC:\codetyphon\typhon\components\BaseUtils\lib\i386-win32 -FuC:\codetyphon\typhon\packager\units\i386-win32 -FuG:\sb\src\branch0650\KafkaGate\KafkaPas\ -FUG:\sb\src\branch0650\KafkaGate\KafkaPas\lib\i386-win32\ -FEG:\sb\src\branch0650\KafkaGate\KafkaPas\win7-x86\native\ -oKafkaPas32.exe -dLCL -dLCLwin32 KafkaPas.lpr"/> 5 | </CONFIG> 6 | -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/KafkaPas.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/i386-win32/KafkaPas.o -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/KafkaPas.or: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/i386-win32/KafkaPas.or -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/KafkaPas.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/i386-win32/KafkaPas.res -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/formmainkafkatest.lfm: -------------------------------------------------------------------------------- 1 | object frmMainKafkaTest: TfrmMainKafkaTest 2 | Left = 590 3 | Height = 768 4 | Top = 245 5 | Width = 1024 6 | Caption = 'Kafka Test' 7 | ClientHeight = 768 8 | ClientWidth = 1024 9 | Font.Name = 'Tahoma' 10 | OnCreate = FormCreate 11 | LCLVersion = '6.0' 12 | object pTop: TPanel 13 | Left = 0 14 | Height = 34 15 | Top = 0 16 | Width = 1024 17 | Align = alTop 18 | Caption = 'Kafka Read and Write Test Program' 19 | Font.Height = 24 20 | ParentFont = False 21 | TabOrder = 0 22 | end 23 | object pLeft: TPanel 24 | Left = 0 25 | Height = 630 26 | Top = 34 27 | Width = 278 28 | Align = alLeft 29 | ClientHeight = 630 30 | ClientWidth = 278 31 | TabOrder = 1 32 | object mParams: TMemo 33 | Left = 1 34 | Height = 602 35 | Top = 27 36 | Width = 276 37 | Align = alClient 38 | Font.Height = 14 39 | Font.Name = 'Tahoma' 40 | ParentFont = False 41 | TabOrder = 0 42 | end 43 | object pLeftCaption: TPanel 44 | Left = 1 45 | Height = 26 46 | Top = 1 47 | Width = 276 48 | Align = alTop 49 | Caption = 'Params' 50 | TabOrder = 1 51 | end 52 | end 53 | object pCenter: TPanel 54 | Left = 283 55 | Height = 630 56 | Top = 34 57 | Width = 741 58 | Align = alClient 59 | ClientHeight = 630 60 | ClientWidth = 741 61 | TabOrder = 2 62 | object mResult: TMemo 63 | Left = 1 64 | Height = 602 65 | Top = 27 66 | Width = 739 67 | Align = alClient 68 | TabOrder = 0 69 | end 70 | object pCenterCaption: TPanel 71 | Left = 1 72 | Height = 26 73 | Top = 1 74 | Width = 739 75 | Align = alTop 76 | Caption = 'Results' 77 | TabOrder = 1 78 | end 79 | end 80 | object pBottom: TPanel 81 | Left = 0 82 | Height = 104 83 | Top = 664 84 | Width = 1024 85 | Align = alBottom 86 | ClientHeight = 104 87 | ClientWidth = 1024 88 | TabOrder = 3 89 | object btnStart: TButton 90 | Left = 8 91 | Height = 88 92 | Top = 8 93 | Width = 150 94 | Caption = 'Start' 95 | OnClick = btnStartClick 96 | TabOrder = 0 97 | end 98 | object btnStop: TButton 99 | Left = 862 100 | Height = 88 101 | Top = 8 102 | Width = 150 103 | Anchors = [akTop, akRight] 104 | Caption = 'Stop' 105 | OnClick = btnStopClick 106 | TabOrder = 1 107 | end 108 | object edBroker: TEdit 109 | Left = 400 110 | Height = 27 111 | Hint = 'Broker Address' 112 | Top = 8 113 | Width = 226 114 | ReadOnly = True 115 | TabOrder = 2 116 | end 117 | object edTopic: TEdit 118 | Left = 400 119 | Height = 27 120 | Hint = 'Topic Name' 121 | Top = 36 122 | Width = 226 123 | ReadOnly = True 124 | TabOrder = 3 125 | end 126 | object edTopicSection: TEdit 127 | Left = 632 128 | Height = 27 129 | Hint = 'Topic Section' 130 | Top = 36 131 | Width = 226 132 | ReadOnly = True 133 | TabOrder = 4 134 | end 135 | object lBrokerCaption: TLabel 136 | Left = 288 137 | Height = 19 138 | Top = 16 139 | Width = 100 140 | AutoSize = False 141 | Caption = 'Broker' 142 | ParentColor = False 143 | end 144 | object lTopicCaption: TLabel 145 | Left = 288 146 | Height = 19 147 | Top = 44 148 | Width = 100 149 | AutoSize = False 150 | Caption = 'Topic' 151 | ParentColor = False 152 | end 153 | object lConfCaption: TLabel 154 | Left = 288 155 | Height = 19 156 | Top = 72 157 | Width = 100 158 | AutoSize = False 159 | Caption = 'Conf' 160 | ParentColor = False 161 | end 162 | object edConfSection: TEdit 163 | Left = 400 164 | Height = 27 165 | Hint = 'Config Section' 166 | Top = 64 167 | Width = 226 168 | ReadOnly = True 169 | TabOrder = 5 170 | end 171 | object rbConsumer: TRadioButton 172 | Left = 174 173 | Height = 23 174 | Top = 24 175 | Width = 92 176 | Caption = 'Consumer' 177 | Checked = True 178 | OnChange = rbConsumerChange 179 | TabOrder = 7 180 | TabStop = True 181 | end 182 | object rbProducer: TRadioButton 183 | Left = 174 184 | Height = 23 185 | Top = 60 186 | Width = 83 187 | Caption = 'Producer' 188 | TabOrder = 6 189 | end 190 | object cbMaxMessageSize: TComboBox 191 | Left = 632 192 | Height = 27 193 | Top = 8 194 | Width = 226 195 | ItemHeight = 19 196 | ItemIndex = 1 197 | Items.Strings = ( 198 | '0 - Whole Message' 199 | '1024 - Trim to 1K Message' 200 | '2048 - Trim to 2K Message' 201 | ) 202 | Style = csDropDownList 203 | TabOrder = 8 204 | Text = '1024 - Trim to 1K Message' 205 | end 206 | object cbSendPause: TComboBox 207 | Left = 632 208 | Height = 27 209 | Top = 64 210 | Width = 226 211 | ItemHeight = 19 212 | ItemIndex = 1 213 | Items.Strings = ( 214 | '10ms send pause' 215 | '100ms send pause' 216 | '200ms send pause' 217 | '300ms send pause' 218 | '400ms send pause' 219 | '500ms send pause' 220 | '600ms send pause' 221 | '700ms send pause' 222 | '800ms send pause' 223 | '900ms send pause' 224 | '1000ms send pause' 225 | '' 226 | ) 227 | Style = csDropDownList 228 | TabOrder = 9 229 | Text = '100ms send pause' 230 | end 231 | end 232 | object splLeftCenter: TSplitter 233 | Left = 278 234 | Height = 630 235 | Top = 34 236 | Width = 5 237 | end 238 | end 239 | -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/formmainkafkatest.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/i386-win32/formmainkafkatest.o -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/formmainkafkatest.ppu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/i386-win32/formmainkafkatest.ppu -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/kafka.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/i386-win32/kafka.o -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/kafka.ppu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/i386-win32/kafka.ppu -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/kafkaclass.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/i386-win32/kafkaclass.o -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/kafkaclass.ppu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/i386-win32/kafkaclass.ppu -------------------------------------------------------------------------------- /KafkaPas/lib/i386-win32/libimpkafka.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/i386-win32/libimpkafka.a -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/KafkaPas.compiled: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="UTF-8"?> 2 | <CONFIG> 3 | <Compiler Value="C:\codetyphon\fpc\fpc32\bin\i386-win32\fpc.exe" Date="1246330200"/> 4 | <Params Value=" -Twin64 -Px86_64 -MObjFPC -Scghi -O1 -g -gl -WG -l -vewnhibq -FiG:\sb\src\branch0650\KafkaGate\KafkaPas\lib\x86_64-win64 -FuC:\codetyphon\typhon\lcl\units\x86_64-win64\win32 -FuC:\codetyphon\typhon\lcl\units\x86_64-win64 -FuC:\codetyphon\typhon\components\BaseUtils\lib\x86_64-win64 -FuC:\codetyphon\typhon\packager\units\x86_64-win64 -FuG:\sb\src\branch0650\KafkaGate\KafkaPas\ -FUG:\sb\src\branch0650\KafkaGate\KafkaPas\lib\x86_64-win64\ -dLCL -dLCLwin32 KafkaPas.lpr"/> 5 | </CONFIG> 6 | -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/KafkaPas.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/x86_64-win64/KafkaPas.o -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/KafkaPas.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/x86_64-win64/KafkaPas.obj -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/KafkaPas.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/x86_64-win64/KafkaPas.res -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/formmainkafkatest.lfm: -------------------------------------------------------------------------------- 1 | object frmMainKafkaTest: TfrmMainKafkaTest 2 | Left = 590 3 | Height = 768 4 | Top = 245 5 | Width = 1024 6 | Caption = 'Kafka Test' 7 | ClientHeight = 768 8 | ClientWidth = 1024 9 | Font.Name = 'Tahoma' 10 | OnCreate = FormCreate 11 | LCLVersion = '6.0' 12 | object pTop: TPanel 13 | Left = 0 14 | Height = 34 15 | Top = 0 16 | Width = 1024 17 | Align = alTop 18 | Caption = 'Kafka Read and Write Test Program' 19 | Font.Height = 24 20 | ParentFont = False 21 | TabOrder = 0 22 | end 23 | object pLeft: TPanel 24 | Left = 0 25 | Height = 630 26 | Top = 34 27 | Width = 278 28 | Align = alLeft 29 | ClientHeight = 630 30 | ClientWidth = 278 31 | TabOrder = 1 32 | object mParams: TMemo 33 | Left = 1 34 | Height = 602 35 | Top = 27 36 | Width = 276 37 | Align = alClient 38 | Font.Height = 14 39 | Font.Name = 'Tahoma' 40 | ParentFont = False 41 | TabOrder = 0 42 | end 43 | object pLeftCaption: TPanel 44 | Left = 1 45 | Height = 26 46 | Top = 1 47 | Width = 276 48 | Align = alTop 49 | Caption = 'Params' 50 | TabOrder = 1 51 | end 52 | end 53 | object pCenter: TPanel 54 | Left = 283 55 | Height = 630 56 | Top = 34 57 | Width = 741 58 | Align = alClient 59 | ClientHeight = 630 60 | ClientWidth = 741 61 | TabOrder = 2 62 | object mResult: TMemo 63 | Left = 1 64 | Height = 602 65 | Top = 27 66 | Width = 739 67 | Align = alClient 68 | TabOrder = 0 69 | end 70 | object pCenterCaption: TPanel 71 | Left = 1 72 | Height = 26 73 | Top = 1 74 | Width = 739 75 | Align = alTop 76 | Caption = 'Results' 77 | TabOrder = 1 78 | end 79 | end 80 | object pBottom: TPanel 81 | Left = 0 82 | Height = 104 83 | Top = 664 84 | Width = 1024 85 | Align = alBottom 86 | ClientHeight = 104 87 | ClientWidth = 1024 88 | TabOrder = 3 89 | object btnStart: TButton 90 | Left = 8 91 | Height = 88 92 | Top = 8 93 | Width = 150 94 | Caption = 'Start' 95 | OnClick = btnStartClick 96 | TabOrder = 0 97 | end 98 | object btnStop: TButton 99 | Left = 862 100 | Height = 88 101 | Top = 8 102 | Width = 150 103 | Anchors = [akTop, akRight] 104 | Caption = 'Stop' 105 | OnClick = btnStopClick 106 | TabOrder = 1 107 | end 108 | object edBroker: TEdit 109 | Left = 400 110 | Height = 27 111 | Hint = 'Broker Address' 112 | Top = 8 113 | Width = 226 114 | ReadOnly = True 115 | TabOrder = 2 116 | end 117 | object edTopic: TEdit 118 | Left = 400 119 | Height = 27 120 | Hint = 'Topic Name' 121 | Top = 36 122 | Width = 226 123 | ReadOnly = True 124 | TabOrder = 3 125 | end 126 | object edTopicSection: TEdit 127 | Left = 632 128 | Height = 27 129 | Hint = 'Topic Section' 130 | Top = 36 131 | Width = 226 132 | ReadOnly = True 133 | TabOrder = 4 134 | end 135 | object lBrokerCaption: TLabel 136 | Left = 288 137 | Height = 19 138 | Top = 16 139 | Width = 100 140 | AutoSize = False 141 | Caption = 'Broker' 142 | ParentColor = False 143 | end 144 | object lTopicCaption: TLabel 145 | Left = 288 146 | Height = 19 147 | Top = 44 148 | Width = 100 149 | AutoSize = False 150 | Caption = 'Topic' 151 | ParentColor = False 152 | end 153 | object lConfCaption: TLabel 154 | Left = 288 155 | Height = 19 156 | Top = 72 157 | Width = 100 158 | AutoSize = False 159 | Caption = 'Conf' 160 | ParentColor = False 161 | end 162 | object edConfSection: TEdit 163 | Left = 400 164 | Height = 27 165 | Hint = 'Config Section' 166 | Top = 64 167 | Width = 226 168 | ReadOnly = True 169 | TabOrder = 5 170 | end 171 | object rbConsumer: TRadioButton 172 | Left = 174 173 | Height = 23 174 | Top = 24 175 | Width = 92 176 | Caption = 'Consumer' 177 | Checked = True 178 | OnChange = rbConsumerChange 179 | TabOrder = 7 180 | TabStop = True 181 | end 182 | object rbProducer: TRadioButton 183 | Left = 174 184 | Height = 23 185 | Top = 60 186 | Width = 83 187 | Caption = 'Producer' 188 | TabOrder = 6 189 | end 190 | object cbMaxMessageSize: TComboBox 191 | Left = 632 192 | Height = 27 193 | Top = 8 194 | Width = 226 195 | ItemHeight = 19 196 | ItemIndex = 1 197 | Items.Strings = ( 198 | '0 - Whole Message' 199 | '1024 - Trim to 1K Message' 200 | '2048 - Trim to 2K Message' 201 | ) 202 | Style = csDropDownList 203 | TabOrder = 8 204 | Text = '1024 - Trim to 1K Message' 205 | end 206 | object cbSendPause: TComboBox 207 | Left = 632 208 | Height = 27 209 | Top = 64 210 | Width = 226 211 | ItemHeight = 19 212 | ItemIndex = 1 213 | Items.Strings = ( 214 | '10ms send pause' 215 | '100ms send pause' 216 | '200ms send pause' 217 | '300ms send pause' 218 | '400ms send pause' 219 | '500ms send pause' 220 | '600ms send pause' 221 | '700ms send pause' 222 | '800ms send pause' 223 | '900ms send pause' 224 | '1000ms send pause' 225 | '' 226 | ) 227 | Style = csDropDownList 228 | TabOrder = 9 229 | Text = '100ms send pause' 230 | end 231 | end 232 | object splLeftCenter: TSplitter 233 | Left = 278 234 | Height = 630 235 | Top = 34 236 | Width = 5 237 | end 238 | end 239 | -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/formmainkafkatest.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/x86_64-win64/formmainkafkatest.o -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/formmainkafkatest.ppu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/x86_64-win64/formmainkafkatest.ppu -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/kafka.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/x86_64-win64/kafka.o -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/kafka.ppu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/x86_64-win64/kafka.ppu -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/kafkaclass.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/x86_64-win64/kafkaclass.o -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/kafkaclass.ppu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/x86_64-win64/kafkaclass.ppu -------------------------------------------------------------------------------- /KafkaPas/lib/x86_64-win64/libimpkafka.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/lib/x86_64-win64/libimpkafka.a -------------------------------------------------------------------------------- /KafkaPas/librdkafka.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/librdkafka.dll -------------------------------------------------------------------------------- /KafkaPas/librdkafkacpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/librdkafkacpp.dll -------------------------------------------------------------------------------- /KafkaPas/msvcr120.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/msvcr120.dll -------------------------------------------------------------------------------- /KafkaPas/producer.ini: -------------------------------------------------------------------------------- 1 | [config] 2 | broker=10.16.14.71:9092 3 | topic=sportfeedxml_2 4 | conf_section=producer_conf 5 | topic_section=producer_topic 6 | 7 | [producer_conf] 8 | message.max.bytes=1500000 9 | socket.keepalive.enable=true 10 | socket.blocking.max.ms=1 11 | queue.buffering.max.messages=2 12 | queue.buffering.max.ms=0 13 | message.send.max.retries=10 14 | retry.backoff.ms=100 15 | compression.codec=none 16 | batch.num.messages=1 17 | delivery.report.only.error=true 18 | socket.nagle.disable=true 19 | 20 | [producer_topic] 21 | offset.store.method=broker 22 | -------------------------------------------------------------------------------- /KafkaPas/win7-x64/native/KafkaPas64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/win7-x64/native/KafkaPas64.exe -------------------------------------------------------------------------------- /KafkaPas/win7-x64/native/consumer.ini: -------------------------------------------------------------------------------- 1 | [config] 2 | broker=10.16.14.71:9092 3 | topic=sportfeedxml_2 4 | conf_section=consumer_conf 5 | topic_section=consumer_topic 6 | 7 | [consumer_conf] 8 | group.id=sbofferdispatcher_live17 9 | socket.keepalive.enable=true 10 | socket.blocking.max.ms=1 11 | #socket.blocking.max.ms=1 12 | socket.nagle.disable=true 13 | queued.min.messages=100000 14 | queued.max.messages.kbytes=1000000000 15 | fetch.wait.max.ms=0 16 | #fetch.message.max.bytes=1024 17 | #fetch.message.max.bytes=1000000000 18 | fetch.min.bytes=1 19 | fetch.wait.max.ms=1 20 | fetch.error.backoff.ms=1 21 | message.max.bytes=100000000 22 | auto.commit.interval.ms=5000 23 | enable.auto.offset.store=true 24 | auto.offset.reset=latest 25 | #enable.partition.eof=false 26 | receive.message.max.bytes=1000000000 27 | api.version.request=false 28 | 29 | [consumer_topic] 30 | offset.store.method=broker 31 | -------------------------------------------------------------------------------- /KafkaPas/win7-x64/native/librdkafka.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/win7-x64/native/librdkafka.dll -------------------------------------------------------------------------------- /KafkaPas/win7-x64/native/librdkafkacpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/win7-x64/native/librdkafkacpp.dll -------------------------------------------------------------------------------- /KafkaPas/win7-x64/native/msvcr120.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/win7-x64/native/msvcr120.dll -------------------------------------------------------------------------------- /KafkaPas/win7-x64/native/producer.ini: -------------------------------------------------------------------------------- 1 | [config] 2 | broker=10.16.14.71:9092 3 | topic=sportfeedxml_2 4 | conf_section=producer_conf 5 | topic_section=producer_topic 6 | 7 | [producer_conf] 8 | message.max.bytes=1500000 9 | socket.keepalive.enable=true 10 | socket.blocking.max.ms=1 11 | queue.buffering.max.messages=2 12 | queue.buffering.max.ms=0 13 | message.send.max.retries=10 14 | retry.backoff.ms=100 15 | compression.codec=none 16 | batch.num.messages=1 17 | delivery.report.only.error=true 18 | socket.nagle.disable=true 19 | 20 | [producer_topic] 21 | offset.store.method=broker 22 | -------------------------------------------------------------------------------- /KafkaPas/win7-x64/native/zlib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/win7-x64/native/zlib.dll -------------------------------------------------------------------------------- /KafkaPas/win7-x86/native/KafkaPas32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/win7-x86/native/KafkaPas32.exe -------------------------------------------------------------------------------- /KafkaPas/win7-x86/native/consumer.ini: -------------------------------------------------------------------------------- 1 | [config] 2 | broker=10.16.14.71:9092 3 | topic=sportfeedxml_2 4 | conf_section=consumer_conf 5 | topic_section=consumer_topic 6 | 7 | [consumer_conf] 8 | group.id=sbofferdispatcher_live17 9 | socket.keepalive.enable=true 10 | socket.blocking.max.ms=1 11 | #socket.blocking.max.ms=1 12 | socket.nagle.disable=true 13 | queued.min.messages=100000 14 | queued.max.messages.kbytes=1000000000 15 | fetch.wait.max.ms=0 16 | #fetch.message.max.bytes=1024 17 | #fetch.message.max.bytes=1000000000 18 | fetch.min.bytes=1 19 | fetch.wait.max.ms=1 20 | fetch.error.backoff.ms=1 21 | message.max.bytes=100000000 22 | auto.commit.interval.ms=5000 23 | enable.auto.offset.store=true 24 | auto.offset.reset=latest 25 | #enable.partition.eof=false 26 | receive.message.max.bytes=1000000000 27 | api.version.request=false 28 | 29 | [consumer_topic] 30 | offset.store.method=broker 31 | -------------------------------------------------------------------------------- /KafkaPas/win7-x86/native/librdkafka.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/win7-x86/native/librdkafka.dll -------------------------------------------------------------------------------- /KafkaPas/win7-x86/native/librdkafkacpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/win7-x86/native/librdkafkacpp.dll -------------------------------------------------------------------------------- /KafkaPas/win7-x86/native/msvcr120.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/win7-x86/native/msvcr120.dll -------------------------------------------------------------------------------- /KafkaPas/win7-x86/native/producer.ini: -------------------------------------------------------------------------------- 1 | [config] 2 | broker=10.16.14.71:9092 3 | topic=sportfeedxml_2 4 | conf_section=producer_conf 5 | topic_section=producer_topic 6 | 7 | [producer_conf] 8 | message.max.bytes=1500000 9 | socket.keepalive.enable=true 10 | socket.blocking.max.ms=1 11 | queue.buffering.max.messages=2 12 | queue.buffering.max.ms=0 13 | message.send.max.retries=10 14 | retry.backoff.ms=100 15 | compression.codec=none 16 | batch.num.messages=1 17 | delivery.report.only.error=true 18 | socket.nagle.disable=true 19 | 20 | [producer_topic] 21 | offset.store.method=broker 22 | -------------------------------------------------------------------------------- /KafkaPas/win7-x86/native/zlib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/win7-x86/native/zlib.dll -------------------------------------------------------------------------------- /KafkaPas/zlib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPas/zlib.dll -------------------------------------------------------------------------------- /KafkaPasConsumer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPasConsumer.png -------------------------------------------------------------------------------- /KafkaPasProducer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/KafkaPasProducer.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KafkaGate 2 | 3 | This library shows how to use Apache Kafka and FreePascal (CodeTyphon 6.40, Lazarus) 4 | This is translation of librdkafka C library (and it contain ZeroMQ wrapper also). 5 | It contain examples for Win64 and Win32 (but it should be portable to Linux, etc..) 6 | There are two ways how to write FreePascal Kafka application. 7 | One way is C procedural style, and the other one is Object Pascal Style. 8 | 9 | </br> 10 | New in this version from 2018-02-27 11 | </br> 12 | New librdkafka 11.3 13 | </br> 14 | Compatibility with Linux 32 and Linux 64 15 | </br> 16 | New Way to sebd message in Kafka Pas Application 17 | </br> 18 | Compiled with new Code Typhon 6.40 19 | </br> 20 | 21 | 22 | KafkaPas is example how to create Kafka GUI application. 23 | KafkaGate is example how to create console application. This application is usefull if you want to connect ZeroMQ Socket and Kafka Topic. You can send and receive messages between them. 24 | 25 | ZeroMQ is excelent message queue library, but without broker (therefore you can lost message). 26 | On the other hand Apache Kafka is message queue broker. So if you like ZeroMQ, but unfortunatelly you need some broker for your project, you can use Kafka to serve that purpose. 27 | 28 | <p align="center"> 29 | <img src="KafkaGate.png"/> 30 | <img src="KafkaPasProducer.png"/> 31 | <img src="KafkaPasConsumer.png"/> 32 | </p> 33 | 34 | <strong>KafkaGate Console Menu</strong> 35 | <p align="left"> 36 | <br>writeln('Menu'); 37 | <br>writeln('1. Start consumer - C Style'); 38 | <br>writeln('2. Start producer - C Style'); 39 | <br>writeln('3. Start consumer - Pas Style'); 40 | <br>writeln('4. Start producer - Pas Style'); 41 | <br>writeln('KAFKA 2 ZEROMQ'); 42 | <br>writeln('config_file: KafkaGate.ini'); 43 | <br>writeln('Purpose of this pipeline is'); 44 | <br>writeln('- put message to kafka->consume message from kafka->send message to 0mq->receive message from 0mq'); 45 | <br>writeln('11. Start Kafka Producer'); 46 | <br>writeln('12. Start Kafka Consumer -> Start ZEROMQ PUSH'); 47 | <br>writeln('13. Start ZEROMQ PULL'); 48 | <br>writeln('ZEROMQ 2 KAFKA'); 49 | <br>writeln('config_file: KafkaGate.ini'); 50 | <br>writeln('Purpose of this pipeline is'); 51 | <br>writeln('- put message to 0mq->consume message from 0mq->send message to kafka->receive message from kafka'); 52 | <br>writeln('21. Start ZERMOQ Producer PUSH'); 53 | <br>writeln('22. Start ZEROMQ PULL -> Kafka Producer'); 54 | <br>writeln('23. Start Kafka Consumer'); 55 | </p> 56 | 57 | 58 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | ################################################################ 2 | 3 | [sportfeedxml] 4 | broker=172.16.20.210:9092 5 | topic=sportfeedxml 6 | conf_section=sportfeedxml_conf 7 | topic_section=sportfeedxml_topic 8 | 9 | 10 | [sportfeedxml_conf] 11 | group.id=sportfeedxml_consumer 12 | socket.keepalive.enable=true 13 | 14 | queued.min.messages=1 15 | queued.max.messages.kbytes=1 16 | 17 | fetch.message.max.bytes=1048576 18 | fetch.min.bytes=1 19 | fetch.wait.max.ms=10 20 | fetch.error.backoff.ms=10 21 | 22 | [sportfeedxml_topic] 23 | offset.store.method=broker 24 | 25 | ################################################################ 26 | 27 | [consumer] 28 | #broker=10.16.14.71:9092 29 | topic=sportfeedxml_2 30 | conf_section=consumer_conf 31 | topic_section=consumer_topic 32 | 33 | 34 | [consumer_conf] 35 | group.id=sbofferdispatcher_live3 36 | socket.keepalive.enable=true 37 | socket.blocking.max.ms=100 38 | #socket.blocking.max.ms=1 39 | socket.nagle.disable=true 40 | 41 | enable.auto.commit=true 42 | auto.commit.interval.ms=100 43 | 44 | queued.min.messages=1 45 | #queued.min.messages=1 46 | queued.max.messages.kbytes=1 47 | 48 | fetch.wait.max.ms=0 49 | #fetch.message.max.bytes=1024 50 | #fetch.message.max.bytes=1000000000 51 | fetch.min.bytes=1 52 | fetch.wait.max.ms=1 53 | 54 | fetch.error.backoff.ms=1 55 | message.max.bytes=1000000000 56 | 57 | 58 | auto.offset.reset=latest 59 | #enable.partition.eof=false 60 | receive.message.max.bytes=1000000000 61 | 62 | api.version.request=false 63 | 64 | [consumer_topic] 65 | #offset.store.method=broker 66 | #offset.store.method=file 67 | offset.store.sync.interval.ms=-1 68 | 69 | 70 | ################################################################ 71 | 72 | 73 | #possible_topics=betslip;eventlotto;eventprematch;eventlive 74 | 75 | [producer] 76 | broker=172.16.20.210:9092 77 | topic=eventlotto 78 | conf_section=producer_conf 79 | topic_section=producer_topic 80 | 81 | 82 | [producer_conf] 83 | message.max.bytes=1500000 84 | socket.keepalive.enable=true 85 | socket.blocking.max.ms=1 86 | queue.buffering.max.messages=2 87 | queue.buffering.max.ms=0 88 | message.send.max.retries=10 89 | retry.backoff.ms=100 90 | compression.codec=none 91 | batch.num.messages=1 92 | delivery.report.only.error=true 93 | 94 | socket.nagle.disable=true 95 | 96 | 97 | [producer_topic] 98 | offset.store.method=broker 99 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(rdkafka_example rdkafka_example.c) 2 | target_link_libraries(rdkafka_example PUBLIC rdkafka) 3 | 4 | add_executable(rdkafka_simple_producer rdkafka_simple_producer.c) 5 | target_link_libraries(rdkafka_simple_producer PUBLIC rdkafka) 6 | 7 | add_executable(rdkafka_consumer_example rdkafka_consumer_example.c) 8 | target_link_libraries(rdkafka_consumer_example PUBLIC rdkafka) 9 | 10 | add_executable(rdkafka_performance rdkafka_performance.c) 11 | target_link_libraries(rdkafka_performance PUBLIC rdkafka) 12 | 13 | add_executable(rdkafka_example_cpp rdkafka_example.cpp) 14 | target_link_libraries(rdkafka_example_cpp PUBLIC rdkafka++) 15 | 16 | add_executable(kafkatest_verifiable_client kafkatest_verifiable_client.cpp) 17 | target_link_libraries(kafkatest_verifiable_client PUBLIC rdkafka++) 18 | 19 | add_executable(rdkafka_consumer_example_cpp rdkafka_consumer_example.cpp) 20 | target_link_libraries(rdkafka_consumer_example_cpp PUBLIC rdkafka++) 21 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | EXAMPLES ?= rdkafka_example rdkafka_performance rdkafka_example_cpp \ 2 | rdkafka_consumer_example rdkafka_consumer_example_cpp \ 3 | kafkatest_verifiable_client rdkafka_simple_producer 4 | 5 | all: $(EXAMPLES) 6 | 7 | include ../mklove/Makefile.base 8 | 9 | CFLAGS += -I../src 10 | CXXFLAGS += -I../src-cpp 11 | 12 | # librdkafka must be compiled with -gstrict-dwarf, but rdkafka_example must not, 13 | # due to some clang bug on OSX 10.9 14 | CPPFLAGS := $(subst strict-dwarf,,$(CPPFLAGS)) 15 | 16 | rdkafka_example: ../src/librdkafka.a rdkafka_example.c 17 | $(CC) $(CPPFLAGS) $(CFLAGS) rdkafka_example.c -o $@ $(LDFLAGS) \ 18 | ../src/librdkafka.a $(LIBS) 19 | @echo "# $@ is ready" 20 | @echo "#" 21 | @echo "# Run producer (write messages on stdin)" 22 | @echo "./$@ -P -t <topic> -p <partition>" 23 | @echo "" 24 | @echo "# or consumer" 25 | @echo "./$@ -C -t <topic> -p <partition>" 26 | @echo "" 27 | @echo "#" 28 | @echo "# More usage options:" 29 | @echo "./$@ -h" 30 | 31 | rdkafka_simple_producer: ../src/librdkafka.a rdkafka_simple_producer.c 32 | $(CC) $(CPPFLAGS) $(CFLAGS) $@.c -o $@ $(LDFLAGS) \ 33 | ../src/librdkafka.a $(LIBS) 34 | 35 | rdkafka_consumer_example: ../src/librdkafka.a rdkafka_consumer_example.c 36 | $(CC) $(CPPFLAGS) $(CFLAGS) rdkafka_consumer_example.c -o $@ $(LDFLAGS) \ 37 | ../src/librdkafka.a $(LIBS) 38 | @echo "# $@ is ready" 39 | @echo "#" 40 | @echo "./$@ <topic[:part]> <topic2[:part]> .." 41 | @echo "" 42 | @echo "#" 43 | @echo "# More usage options:" 44 | @echo "./$@ -h" 45 | 46 | rdkafka_performance: ../src/librdkafka.a rdkafka_performance.c 47 | $(CC) $(CPPFLAGS) $(CFLAGS) rdkafka_performance.c -o $@ $(LDFLAGS) \ 48 | ../src/librdkafka.a $(LIBS) 49 | @echo "# $@ is ready" 50 | @echo "#" 51 | @echo "# Run producer" 52 | @echo "./$@ -P -t <topic> -p <partition> -s <msgsize>" 53 | @echo "" 54 | @echo "# or consumer" 55 | @echo "./$@ -C -t <topic> -p <partition>" 56 | @echo "" 57 | @echo "#" 58 | @echo "# More usage options:" 59 | @echo "./$@ -h" 60 | 61 | 62 | rdkafka_example_cpp: ../src-cpp/librdkafka++.a ../src/librdkafka.a rdkafka_example.cpp 63 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) rdkafka_example.cpp -o $@ $(LDFLAGS) \ 64 | ../src-cpp/librdkafka++.a ../src/librdkafka.a $(LIBS) -lstdc++ 65 | 66 | kafkatest_verifiable_client: ../src-cpp/librdkafka++.a ../src/librdkafka.a kafkatest_verifiable_client.cpp 67 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) kafkatest_verifiable_client.cpp -o $@ $(LDFLAGS) \ 68 | ../src-cpp/librdkafka++.a ../src/librdkafka.a $(LIBS) -lstdc++ 69 | 70 | 71 | rdkafka_consumer_example_cpp: ../src-cpp/librdkafka++.a ../src/librdkafka.a rdkafka_consumer_example.cpp 72 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) rdkafka_consumer_example.cpp -o $@ $(LDFLAGS) \ 73 | ../src-cpp/librdkafka++.a ../src/librdkafka.a $(LIBS) -lstdc++ 74 | 75 | rdkafka_zookeeper_example: ../src/librdkafka.a rdkafka_zookeeper_example.c 76 | $(CC) $(CPPFLAGS) $(CFLAGS) -I/usr/include/zookeeper rdkafka_zookeeper_example.c -o $@ $(LDFLAGS) \ 77 | ../src/librdkafka.a $(LIBS) -lzookeeper_mt -ljansson 78 | @echo "# $@ is ready" 79 | @echo "#" 80 | @echo "# Run producer (write messages on stdin)" 81 | @echo "./$@ -P -t <topic> -p <partition>" 82 | @echo "" 83 | @echo "# or consumer" 84 | @echo "./$@ -C -t <topic> -p <partition>" 85 | @echo "" 86 | @echo "#" 87 | @echo "# More usage options:" 88 | @echo "./$@ -h" 89 | 90 | clean: 91 | rm -f $(EXAMPLES) 92 | 93 | -------------------------------------------------------------------------------- /examples/globals.json: -------------------------------------------------------------------------------- 1 | {"VerifiableConsumer": 2 | { 3 | "class": "kafkatest.services.verifiable_client.VerifiableClientApp", 4 | "exec_cmd": "/vagrant/tests/c/kafkatest_verifiable_client --consumer --debug cgrp,topic,protocol,broker" 5 | }, 6 | "VerifiableProducer": 7 | { 8 | "class": "kafkatest.services.verifiable_client.VerifiableClientApp", 9 | "exec_cmd": "/vagrant/tests/c/kafkatest_verifiable_client --producer --debug topic,broker" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/rdkafka_consumer_example.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * librdkafka - Apache Kafka C library 3 | * 4 | * Copyright (c) 2014, Magnus Edenhill 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, 13 | * this list of conditions and the following disclaimer in the documentation 14 | * and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * Apache Kafka consumer & producer example programs 31 | * using the Kafka driver from librdkafka 32 | * (https://github.com/edenhill/librdkafka) 33 | */ 34 | 35 | #include <iostream> 36 | #include <string> 37 | #include <cstdlib> 38 | #include <cstdio> 39 | #include <csignal> 40 | #include <cstring> 41 | 42 | #ifndef _MSC_VER 43 | #include <sys/time.h> 44 | #endif 45 | 46 | #ifdef _MSC_VER 47 | #include "../win32/wingetopt.h" 48 | #include <atltime.h> 49 | #elif _AIX 50 | #include <unistd.h> 51 | #else 52 | #include <getopt.h> 53 | #include <unistd.h> 54 | #endif 55 | 56 | /* 57 | * Typically include path in a real application would be 58 | * #include <librdkafka/rdkafkacpp.h> 59 | */ 60 | #include "rdkafkacpp.h" 61 | 62 | 63 | 64 | static bool run = true; 65 | static bool exit_eof = false; 66 | static int eof_cnt = 0; 67 | static int partition_cnt = 0; 68 | static int verbosity = 1; 69 | static long msg_cnt = 0; 70 | static int64_t msg_bytes = 0; 71 | static void sigterm (int sig) { 72 | run = false; 73 | } 74 | 75 | 76 | /** 77 | * @brief format a string timestamp from the current time 78 | */ 79 | static void print_time () { 80 | #ifndef _MSC_VER 81 | struct timeval tv; 82 | char buf[64]; 83 | gettimeofday(&tv, NULL); 84 | strftime(buf, sizeof(buf) - 1, "%Y-%m-%d %H:%M:%S", localtime(&tv.tv_sec)); 85 | fprintf(stderr, "%s.%03d: ", buf, (int)(tv.tv_usec / 1000)); 86 | #else 87 | std::wcerr << CTime::GetCurrentTime().Format(_T("%Y-%m-%d %H:%M:%S")).GetString() 88 | << ": "; 89 | #endif 90 | } 91 | class ExampleEventCb : public RdKafka::EventCb { 92 | public: 93 | void event_cb (RdKafka::Event &event) { 94 | 95 | print_time(); 96 | 97 | switch (event.type()) 98 | { 99 | case RdKafka::Event::EVENT_ERROR: 100 | std::cerr << "ERROR (" << RdKafka::err2str(event.err()) << "): " << 101 | event.str() << std::endl; 102 | if (event.err() == RdKafka::ERR__ALL_BROKERS_DOWN) 103 | run = false; 104 | break; 105 | 106 | case RdKafka::Event::EVENT_STATS: 107 | std::cerr << "\"STATS\": " << event.str() << std::endl; 108 | break; 109 | 110 | case RdKafka::Event::EVENT_LOG: 111 | fprintf(stderr, "LOG-%i-%s: %s\n", 112 | event.severity(), event.fac().c_str(), event.str().c_str()); 113 | break; 114 | 115 | case RdKafka::Event::EVENT_THROTTLE: 116 | std::cerr << "THROTTLED: " << event.throttle_time() << "ms by " << 117 | event.broker_name() << " id " << (int)event.broker_id() << std::endl; 118 | break; 119 | 120 | default: 121 | std::cerr << "EVENT " << event.type() << 122 | " (" << RdKafka::err2str(event.err()) << "): " << 123 | event.str() << std::endl; 124 | break; 125 | } 126 | } 127 | }; 128 | 129 | 130 | class ExampleRebalanceCb : public RdKafka::RebalanceCb { 131 | private: 132 | static void part_list_print (const std::vector<RdKafka::TopicPartition*>&partitions){ 133 | for (unsigned int i = 0 ; i < partitions.size() ; i++) 134 | std::cerr << partitions[i]->topic() << 135 | "[" << partitions[i]->partition() << "], "; 136 | std::cerr << "\n"; 137 | } 138 | 139 | public: 140 | void rebalance_cb (RdKafka::KafkaConsumer *consumer, 141 | RdKafka::ErrorCode err, 142 | std::vector<RdKafka::TopicPartition*> &partitions) { 143 | std::cerr << "RebalanceCb: " << RdKafka::err2str(err) << ": "; 144 | 145 | part_list_print(partitions); 146 | 147 | if (err == RdKafka::ERR__ASSIGN_PARTITIONS) { 148 | consumer->assign(partitions); 149 | partition_cnt = (int)partitions.size(); 150 | } else { 151 | consumer->unassign(); 152 | partition_cnt = 0; 153 | } 154 | eof_cnt = 0; 155 | } 156 | }; 157 | 158 | 159 | void msg_consume(RdKafka::Message* message, void* opaque) { 160 | switch (message->err()) { 161 | case RdKafka::ERR__TIMED_OUT: 162 | break; 163 | 164 | case RdKafka::ERR_NO_ERROR: 165 | /* Real message */ 166 | msg_cnt++; 167 | msg_bytes += message->len(); 168 | if (verbosity >= 3) 169 | std::cerr << "Read msg at offset " << message->offset() << std::endl; 170 | RdKafka::MessageTimestamp ts; 171 | ts = message->timestamp(); 172 | if (verbosity >= 2 && 173 | ts.type != RdKafka::MessageTimestamp::MSG_TIMESTAMP_NOT_AVAILABLE) { 174 | std::string tsname = "?"; 175 | if (ts.type == RdKafka::MessageTimestamp::MSG_TIMESTAMP_CREATE_TIME) 176 | tsname = "create time"; 177 | else if (ts.type == RdKafka::MessageTimestamp::MSG_TIMESTAMP_LOG_APPEND_TIME) 178 | tsname = "log append time"; 179 | std::cout << "Timestamp: " << tsname << " " << ts.timestamp << std::endl; 180 | } 181 | if (verbosity >= 2 && message->key()) { 182 | std::cout << "Key: " << *message->key() << std::endl; 183 | } 184 | if (verbosity >= 1) { 185 | printf("%.*s\n", 186 | static_cast<int>(message->len()), 187 | static_cast<const char *>(message->payload())); 188 | } 189 | break; 190 | 191 | case RdKafka::ERR__PARTITION_EOF: 192 | /* Last message */ 193 | if (exit_eof && ++eof_cnt == partition_cnt) { 194 | std::cerr << "%% EOF reached for all " << partition_cnt << 195 | " partition(s)" << std::endl; 196 | run = false; 197 | } 198 | break; 199 | 200 | case RdKafka::ERR__UNKNOWN_TOPIC: 201 | case RdKafka::ERR__UNKNOWN_PARTITION: 202 | std::cerr << "Consume failed: " << message->errstr() << std::endl; 203 | run = false; 204 | break; 205 | 206 | default: 207 | /* Errors */ 208 | std::cerr << "Consume failed: " << message->errstr() << std::endl; 209 | run = false; 210 | } 211 | } 212 | 213 | 214 | class ExampleConsumeCb : public RdKafka::ConsumeCb { 215 | public: 216 | void consume_cb (RdKafka::Message &msg, void *opaque) { 217 | msg_consume(&msg, opaque); 218 | } 219 | }; 220 | 221 | 222 | 223 | int main (int argc, char **argv) { 224 | std::string brokers = "localhost"; 225 | std::string errstr; 226 | std::string topic_str; 227 | std::string mode; 228 | std::string debug; 229 | std::vector<std::string> topics; 230 | bool do_conf_dump = false; 231 | int opt; 232 | int use_ccb = 0; 233 | 234 | /* 235 | * Create configuration objects 236 | */ 237 | RdKafka::Conf *conf = RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL); 238 | RdKafka::Conf *tconf = RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC); 239 | 240 | ExampleRebalanceCb ex_rebalance_cb; 241 | conf->set("rebalance_cb", &ex_rebalance_cb, errstr); 242 | 243 | while ((opt = getopt(argc, argv, "g:b:z:qd:eX:AM:f:qv")) != -1) { 244 | switch (opt) { 245 | case 'g': 246 | if (conf->set("group.id", optarg, errstr) != RdKafka::Conf::CONF_OK) { 247 | std::cerr << errstr << std::endl; 248 | exit(1); 249 | } 250 | break; 251 | case 'b': 252 | brokers = optarg; 253 | break; 254 | case 'z': 255 | if (conf->set("compression.codec", optarg, errstr) != 256 | RdKafka::Conf::CONF_OK) { 257 | std::cerr << errstr << std::endl; 258 | exit(1); 259 | } 260 | break; 261 | case 'e': 262 | exit_eof = true; 263 | break; 264 | case 'd': 265 | debug = optarg; 266 | break; 267 | case 'M': 268 | if (conf->set("statistics.interval.ms", optarg, errstr) != 269 | RdKafka::Conf::CONF_OK) { 270 | std::cerr << errstr << std::endl; 271 | exit(1); 272 | } 273 | break; 274 | case 'X': 275 | { 276 | char *name, *val; 277 | 278 | if (!strcmp(optarg, "dump")) { 279 | do_conf_dump = true; 280 | continue; 281 | } 282 | 283 | name = optarg; 284 | if (!(val = strchr(name, '='))) { 285 | std::cerr << "%% Expected -X property=value, not " << 286 | name << std::endl; 287 | exit(1); 288 | } 289 | 290 | *val = '\0'; 291 | val++; 292 | 293 | /* Try "topic." prefixed properties on topic 294 | * conf first, and then fall through to global if 295 | * it didnt match a topic configuration property. */ 296 | RdKafka::Conf::ConfResult res = RdKafka::Conf::CONF_UNKNOWN; 297 | if (!strncmp(name, "topic.", strlen("topic."))) 298 | res = tconf->set(name+strlen("topic."), val, errstr); 299 | if (res == RdKafka::Conf::CONF_UNKNOWN) 300 | res = conf->set(name, val, errstr); 301 | 302 | if (res != RdKafka::Conf::CONF_OK) { 303 | std::cerr << errstr << std::endl; 304 | exit(1); 305 | } 306 | } 307 | break; 308 | 309 | case 'f': 310 | if (!strcmp(optarg, "ccb")) 311 | use_ccb = 1; 312 | else { 313 | std::cerr << "Unknown option: " << optarg << std::endl; 314 | exit(1); 315 | } 316 | break; 317 | 318 | case 'q': 319 | verbosity--; 320 | break; 321 | 322 | case 'v': 323 | verbosity++; 324 | break; 325 | 326 | default: 327 | goto usage; 328 | } 329 | } 330 | 331 | for (; optind < argc ; optind++) 332 | topics.push_back(std::string(argv[optind])); 333 | 334 | if (topics.empty() || optind != argc) { 335 | usage: 336 | fprintf(stderr, 337 | "Usage: %s -g <group-id> [options] topic1 topic2..\n" 338 | "\n" 339 | "librdkafka version %s (0x%08x)\n" 340 | "\n" 341 | " Options:\n" 342 | " -g <group-id> Consumer group id\n" 343 | " -b <brokers> Broker address (localhost:9092)\n" 344 | " -z <codec> Enable compression:\n" 345 | " none|gzip|snappy\n" 346 | " -e Exit consumer when last message\n" 347 | " in partition has been received.\n" 348 | " -d [facs..] Enable debugging contexts:\n" 349 | " %s\n" 350 | " -M <intervalms> Enable statistics\n" 351 | " -X <prop=name> Set arbitrary librdkafka " 352 | "configuration property\n" 353 | " Properties prefixed with \"topic.\" " 354 | "will be set on topic object.\n" 355 | " Use '-X list' to see the full list\n" 356 | " of supported properties.\n" 357 | " -f <flag> Set option:\n" 358 | " ccb - use consume_callback\n" 359 | " -q Quiet / Decrease verbosity\n" 360 | " -v Increase verbosity\n" 361 | "\n" 362 | "\n", 363 | argv[0], 364 | RdKafka::version_str().c_str(), RdKafka::version(), 365 | RdKafka::get_debug_contexts().c_str()); 366 | exit(1); 367 | } 368 | 369 | 370 | /* 371 | * Set configuration properties 372 | */ 373 | conf->set("metadata.broker.list", brokers, errstr); 374 | 375 | if (!debug.empty()) { 376 | if (conf->set("debug", debug, errstr) != RdKafka::Conf::CONF_OK) { 377 | std::cerr << errstr << std::endl; 378 | exit(1); 379 | } 380 | } 381 | 382 | ExampleConsumeCb ex_consume_cb; 383 | 384 | if(use_ccb) { 385 | conf->set("consume_cb", &ex_consume_cb, errstr); 386 | } 387 | 388 | ExampleEventCb ex_event_cb; 389 | conf->set("event_cb", &ex_event_cb, errstr); 390 | 391 | if (do_conf_dump) { 392 | int pass; 393 | 394 | for (pass = 0 ; pass < 2 ; pass++) { 395 | std::list<std::string> *dump; 396 | if (pass == 0) { 397 | dump = conf->dump(); 398 | std::cout << "# Global config" << std::endl; 399 | } else { 400 | dump = tconf->dump(); 401 | std::cout << "# Topic config" << std::endl; 402 | } 403 | 404 | for (std::list<std::string>::iterator it = dump->begin(); 405 | it != dump->end(); ) { 406 | std::cout << *it << " = "; 407 | it++; 408 | std::cout << *it << std::endl; 409 | it++; 410 | } 411 | std::cout << std::endl; 412 | } 413 | exit(0); 414 | } 415 | 416 | conf->set("default_topic_conf", tconf, errstr); 417 | delete tconf; 418 | 419 | signal(SIGINT, sigterm); 420 | signal(SIGTERM, sigterm); 421 | 422 | 423 | /* 424 | * Consumer mode 425 | */ 426 | 427 | /* 428 | * Create consumer using accumulated global configuration. 429 | */ 430 | RdKafka::KafkaConsumer *consumer = RdKafka::KafkaConsumer::create(conf, errstr); 431 | if (!consumer) { 432 | std::cerr << "Failed to create consumer: " << errstr << std::endl; 433 | exit(1); 434 | } 435 | 436 | delete conf; 437 | 438 | std::cout << "% Created consumer " << consumer->name() << std::endl; 439 | 440 | 441 | /* 442 | * Subscribe to topics 443 | */ 444 | RdKafka::ErrorCode err = consumer->subscribe(topics); 445 | if (err) { 446 | std::cerr << "Failed to subscribe to " << topics.size() << " topics: " 447 | << RdKafka::err2str(err) << std::endl; 448 | exit(1); 449 | } 450 | 451 | /* 452 | * Consume messages 453 | */ 454 | while (run) { 455 | RdKafka::Message *msg = consumer->consume(1000); 456 | if (!use_ccb) { 457 | msg_consume(msg, NULL); 458 | } 459 | delete msg; 460 | } 461 | 462 | #ifndef _MSC_VER 463 | alarm(10); 464 | #endif 465 | 466 | /* 467 | * Stop consumer 468 | */ 469 | consumer->close(); 470 | delete consumer; 471 | 472 | std::cerr << "% Consumed " << msg_cnt << " messages (" 473 | << msg_bytes << " bytes)" << std::endl; 474 | 475 | /* 476 | * Wait for RdKafka to decommission. 477 | * This is not strictly needed (with check outq_len() above), but 478 | * allows RdKafka to clean up all its resources before the application 479 | * exits so that memory profilers such as valgrind wont complain about 480 | * memory leaks. 481 | */ 482 | RdKafka::wait_destroyed(5000); 483 | 484 | return 0; 485 | } 486 | -------------------------------------------------------------------------------- /examples/rdkafka_simple_producer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * librdkafka - Apache Kafka C library 3 | * 4 | * Copyright (c) 2017, Magnus Edenhill 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright notice, 13 | * this list of conditions and the following disclaimer in the documentation 14 | * and/or other materials provided with the distribution. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | * POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** 30 | * Simple Apache Kafka producer 31 | * using the Kafka driver from librdkafka 32 | * (https://github.com/edenhill/librdkafka) 33 | */ 34 | 35 | #include <stdio.h> 36 | #include <signal.h> 37 | #include <string.h> 38 | 39 | 40 | /* Typical include path would be <librdkafka/rdkafka.h>, but this program 41 | * is builtin from within the librdkafka source tree and thus differs. */ 42 | #include "rdkafka.h" 43 | 44 | 45 | static int run = 1; 46 | 47 | /** 48 | * @brief Signal termination of program 49 | */ 50 | static void stop (int sig) { 51 | run = 0; 52 | fclose(stdin); /* abort fgets() */ 53 | } 54 | 55 | 56 | /** 57 | * @brief Message delivery report callback. 58 | * 59 | * This callback is called exactly once per message, indicating if 60 | * the message was succesfully delivered 61 | * (rkmessage->err == RD_KAFKA_RESP_ERR_NO_ERROR) or permanently 62 | * failed delivery (rkmessage->err != RD_KAFKA_RESP_ERR_NO_ERROR). 63 | * 64 | * The callback is triggered from rd_kafka_poll() and executes on 65 | * the application's thread. 66 | */ 67 | static void dr_msg_cb (rd_kafka_t *rk, 68 | const rd_kafka_message_t *rkmessage, void *opaque) { 69 | if (rkmessage->err) 70 | fprintf(stderr, "%% Message delivery failed: %s\n", 71 | rd_kafka_err2str(rkmessage->err)); 72 | else 73 | fprintf(stderr, 74 | "%% Message delivered (%zd bytes, " 75 | "partition %"PRId32")\n", 76 | rkmessage->len, rkmessage->partition); 77 | 78 | /* The rkmessage is destroyed automatically by librdkafka */ 79 | } 80 | 81 | 82 | 83 | int main (int argc, char **argv) { 84 | rd_kafka_t *rk; /* Producer instance handle */ 85 | rd_kafka_topic_t *rkt; /* Topic object */ 86 | rd_kafka_conf_t *conf; /* Temporary configuration object */ 87 | char errstr[512]; /* librdkafka API error reporting buffer */ 88 | char buf[512]; /* Message value temporary buffer */ 89 | const char *brokers; /* Argument: broker list */ 90 | const char *topic; /* Argument: topic to produce to */ 91 | 92 | /* 93 | * Argument validation 94 | */ 95 | if (argc != 3) { 96 | fprintf(stderr, "%% Usage: %s <broker> <topic>\n", argv[0]); 97 | return 1; 98 | } 99 | 100 | brokers = argv[1]; 101 | topic = argv[2]; 102 | 103 | 104 | /* 105 | * Create Kafka client configuration place-holder 106 | */ 107 | conf = rd_kafka_conf_new(); 108 | 109 | /* Set bootstrap broker(s) as a comma-separated list of 110 | * host or host:port (default port 9092). 111 | * librdkafka will use the bootstrap brokers to acquire the full 112 | * set of brokers from the cluster. */ 113 | if (rd_kafka_conf_set(conf, "bootstrap.servers", brokers, 114 | errstr, sizeof(errstr)) != RD_KAFKA_CONF_OK) { 115 | fprintf(stderr, "%s\n", errstr); 116 | return 1; 117 | } 118 | 119 | /* Set the delivery report callback. 120 | * This callback will be called once per message to inform 121 | * the application if delivery succeeded or failed. 122 | * See dr_msg_cb() above. */ 123 | rd_kafka_conf_set_dr_msg_cb(conf, dr_msg_cb); 124 | 125 | 126 | /* 127 | * Create producer instance. 128 | * 129 | * NOTE: rd_kafka_new() takes ownership of the conf object 130 | * and the application must not reference it again after 131 | * this call. 132 | */ 133 | rk = rd_kafka_new(RD_KAFKA_PRODUCER, conf, errstr, sizeof(errstr)); 134 | if (!rk) { 135 | fprintf(stderr, 136 | "%% Failed to create new producer: %s\n", errstr); 137 | return 1; 138 | } 139 | 140 | 141 | /* Create topic object that will be reused for each message 142 | * produced. 143 | * 144 | * Both the producer instance (rd_kafka_t) and topic objects (topic_t) 145 | * are long-lived objects that should be reused as much as possible. 146 | */ 147 | rkt = rd_kafka_topic_new(rk, topic, NULL); 148 | if (!rkt) { 149 | fprintf(stderr, "%% Failed to create topic object: %s\n", 150 | rd_kafka_err2str(rd_kafka_last_error())); 151 | rd_kafka_destroy(rk); 152 | return 1; 153 | } 154 | 155 | /* Signal handler for clean shutdown */ 156 | signal(SIGINT, stop); 157 | 158 | fprintf(stderr, 159 | "%% Type some text and hit enter to produce message\n" 160 | "%% Or just hit enter to only serve delivery reports\n" 161 | "%% Press Ctrl-C or Ctrl-D to exit\n"); 162 | 163 | while (run && fgets(buf, sizeof(buf), stdin)) { 164 | size_t len = strlen(buf); 165 | 166 | if (buf[len-1] == '\n') /* Remove newline */ 167 | buf[--len] = '\0'; 168 | 169 | if (len == 0) { 170 | /* Empty line: only serve delivery reports */ 171 | rd_kafka_poll(rk, 0/*non-blocking */); 172 | continue; 173 | } 174 | 175 | /* 176 | * Send/Produce message. 177 | * This is an asynchronous call, on success it will only 178 | * enqueue the message on the internal producer queue. 179 | * The actual delivery attempts to the broker are handled 180 | * by background threads. 181 | * The previously registered delivery report callback 182 | * (dr_msg_cb) is used to signal back to the application 183 | * when the message has been delivered (or failed). 184 | */ 185 | retry: 186 | if (rd_kafka_produce( 187 | /* Topic object */ 188 | rkt, 189 | /* Use builtin partitioner to select partition*/ 190 | RD_KAFKA_PARTITION_UA, 191 | /* Make a copy of the payload. */ 192 | RD_KAFKA_MSG_F_COPY, 193 | /* Message payload (value) and length */ 194 | buf, len, 195 | /* Optional key and its length */ 196 | NULL, 0, 197 | /* Message opaque, provided in 198 | * delivery report callback as 199 | * msg_opaque. */ 200 | NULL) == -1) { 201 | /** 202 | * Failed to *enqueue* message for producing. 203 | */ 204 | fprintf(stderr, 205 | "%% Failed to produce to topic %s: %s\n", 206 | rd_kafka_topic_name(rkt), 207 | rd_kafka_err2str(rd_kafka_last_error())); 208 | 209 | /* Poll to handle delivery reports */ 210 | if (rd_kafka_last_error() == 211 | RD_KAFKA_RESP_ERR__QUEUE_FULL) { 212 | /* If the internal queue is full, wait for 213 | * messages to be delivered and then retry. 214 | * The internal queue represents both 215 | * messages to be sent and messages that have 216 | * been sent or failed, awaiting their 217 | * delivery report callback to be called. 218 | * 219 | * The internal queue is limited by the 220 | * configuration property 221 | * queue.buffering.max.messages */ 222 | rd_kafka_poll(rk, 1000/*block for max 1000ms*/); 223 | goto retry; 224 | } 225 | } else { 226 | fprintf(stderr, "%% Enqueued message (%zd bytes) " 227 | "for topic %s\n", 228 | len, rd_kafka_topic_name(rkt)); 229 | } 230 | 231 | 232 | /* A producer application should continually serve 233 | * the delivery report queue by calling rd_kafka_poll() 234 | * at frequent intervals. 235 | * Either put the poll call in your main loop, or in a 236 | * dedicated thread, or call it after every 237 | * rd_kafka_produce() call. 238 | * Just make sure that rd_kafka_poll() is still called 239 | * during periods where you are not producing any messages 240 | * to make sure previously produced messages have their 241 | * delivery report callback served (and any other callbacks 242 | * you register). */ 243 | rd_kafka_poll(rk, 0/*non-blocking*/); 244 | } 245 | 246 | 247 | /* Wait for final messages to be delivered or fail. 248 | * rd_kafka_flush() is an abstraction over rd_kafka_poll() which 249 | * waits for all messages to be delivered. */ 250 | fprintf(stderr, "%% Flushing final messages..\n"); 251 | rd_kafka_flush(rk, 10*1000 /* wait for max 10 seconds */); 252 | 253 | /* Destroy topic object */ 254 | rd_kafka_topic_destroy(rkt); 255 | 256 | /* Destroy the producer instance */ 257 | rd_kafka_destroy(rk); 258 | 259 | return 0; 260 | } 261 | -------------------------------------------------------------------------------- /heaptrc.trc: -------------------------------------------------------------------------------- 1 | G:\sb\src\branch0650\KafkaGate\KafkaGate.exe 2 | Heap dump by heaptrc unit 3 | 33631 memory blocks allocated : 559232967/559375064 4 | 33631 memory blocks freed : 559232967/559375064 5 | 0 unfreed memory blocks : 0 6 | True heap size : 425984 (112 used in System startup) 7 | True free heap : 425872 8 | G:\sb\src\branch0650\KafkaGate\KafkaGate.exe 9 | Heap dump by heaptrc unit 10 | 96 memory blocks allocated : 6557090/6557344 11 | 96 memory blocks freed : 6557090/6557344 12 | 0 unfreed memory blocks : 0 13 | True heap size : 196608 (112 used in System startup) 14 | True free heap : 196496 15 | -------------------------------------------------------------------------------- /kafka2zero.pas: -------------------------------------------------------------------------------- 1 | unit Kafka2Zero; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | interface 6 | 7 | uses 8 | Classes, SysUtils, Crt, 9 | Kafka, KafkaClass, zmq, ZMQClass; 10 | 11 | type 12 | 13 | { TKafkaConsumer2ZeroMQ } 14 | 15 | TKafkaConsumer2ZeroMQ = class 16 | _0MQSocket: T0MQSocket; 17 | 18 | constructor Create(In0MQSocket: T0MQSocket); 19 | procedure OnKafkaMessageReceived(InMessage: String; InKey: String; OutMsg: Prd_kafka_message_t); 20 | procedure OnKafkaMessageEOF(InMessage: String); 21 | procedure OnKafkaMessageErr(InError: String); 22 | procedure OnKafkaTick(InWhat: String); 23 | end; 24 | 25 | procedure StartKafkaProducer_11(InIniFileName: String); 26 | procedure StartKafkaConsumer_12(InIniFileName: String); 27 | procedure StartZeroMQConsumer_13(InIniFileName: String); 28 | 29 | implementation 30 | 31 | procedure WriteStatus(InString: String); 32 | begin 33 | Writeln(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now) + ' ' + InString); 34 | end; 35 | 36 | // callback for Kafka send message 37 | procedure Kafka2Zero_dr_msg_cb (rk: Prd_kafka_t; rkmessage: Prd_kafka_message_t; opaque: Pointer); cdecl; 38 | begin 39 | if (rkmessage^.err <> 0) then begin 40 | WriteStatus(Format('Message delivery failed: %s', [rd_kafka_err2str(rkmessage^.err)])); 41 | end 42 | else begin 43 | WriteStatus(Format('Message delivered (bytes: %d, partition: %d)', [rkmessage^.len, rkmessage^.partion])); 44 | end; 45 | end; 46 | 47 | 48 | { TKafkaConsumer2ZeroMQ } 49 | 50 | constructor TKafkaConsumer2ZeroMQ.Create(In0MQSocket: T0MQSocket); 51 | begin 52 | _0MQSocket := In0MQSocket; 53 | end; 54 | 55 | procedure TKafkaConsumer2ZeroMQ.OnKafkaMessageReceived(InMessage: String; 56 | InKey: String; OutMsg: Prd_kafka_message_t); 57 | var MyError: Integer; 58 | begin 59 | WriteStatus('ReceiveMessage: ' + InMessage); 60 | WriteStatus('Send Message'); 61 | try 62 | MyError := _0MQSocket.Send(InMessage); 63 | if MyError > 0 then begin 64 | WriteStatus('Message Sent: ' + InMessage) 65 | end 66 | except 67 | on E: Exception do begin 68 | WriteStatus('Error: ' + e.Message); 69 | end; 70 | end 71 | end; 72 | 73 | procedure TKafkaConsumer2ZeroMQ.OnKafkaMessageEOF(InMessage: String); 74 | begin 75 | WriteStatus('ReceiveKafkaEOF'); 76 | end; 77 | 78 | procedure TKafkaConsumer2ZeroMQ.OnKafkaMessageErr(InError: String); 79 | begin 80 | WriteStatus('ReceiveKafkaERR: ' + InError); 81 | end; 82 | 83 | procedure TKafkaConsumer2ZeroMQ.OnKafkaTick(InWhat: String); 84 | begin 85 | // WriteStatus('ReceiveKafkaTick: ' + InWhat); 86 | end; 87 | 88 | 89 | procedure StartKafkaProducer_11(InIniFileName: String); 90 | var MyProducer: TKafkaProducer; 91 | MyKafkaSetup: TKafkaSetup; 92 | F: Integer; 93 | My_dr_msg_cb: TProc_dr_msg_cb; 94 | MyKey, MyMessage: String; 95 | begin 96 | MyProducer := nil; 97 | try 98 | KafkaReadConfiguration(InIniFileName, 'kafka_producer', MyKafkaSetup); 99 | 100 | MyProducer := TKafkaProducer.Create(True); 101 | 102 | My_dr_msg_cb := @Kafka2Zero_dr_msg_cb; 103 | MyProducer.StartProducer(MyKafkaSetup, My_dr_msg_cb); 104 | 105 | for F := 0 to 1000 do begin 106 | if KeyPressed then begin // <--- CRT function to test key press 107 | if ReadKey = ^C then begin // read the key pressed 108 | WriteStatus('Ctrl-C pressed'); 109 | Break; 110 | end; 111 | end; 112 | 113 | MyKey := IntToStr(F mod 100); 114 | MyMessage := FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now); 115 | MyProducer.ProduceMessage(MyKey, MyMessage); 116 | Sleep(250); 117 | end; 118 | 119 | if MyProducer <> nil then FreeAndNil(MyProducer); 120 | except 121 | on E: Exception do begin 122 | WriteStatus('Error: ' + E.Message); 123 | if MyProducer <> nil then FreeAndNil(MyProducer); 124 | end; 125 | end; 126 | end; 127 | 128 | procedure StartKafkaConsumer_12(InIniFileName: String); 129 | var MyConsumer: TKafkaConsumer; 130 | MyKafkaSetup: TKafkaSetup; 131 | 132 | My0MQContext: T0MQContext; 133 | My0MQSocket: T0MQSocket; 134 | My0MQSetup: T0MQSetup; 135 | 136 | MySpecificKafkaConsumer: TKafkaConsumer2ZeroMQ; 137 | MyMaxReadBytes: Integer; 138 | begin 139 | MyMaxReadBytes := 128; // I want only 128 bytes messages - rest is trimmed 140 | MyConsumer := nil; 141 | My0MQSocket := nil; 142 | MySpecificKafkaConsumer := nil; 143 | 144 | try 145 | // read kafka and 0mq configuration 146 | KafkaReadConfiguration(InIniFileName, 'kafka_consumer', MyKafkaSetup); 147 | ZeroMQReadConfiguration(InIniFileName, 'ZERO_SENDER', My0MQSetup); 148 | 149 | // create kafka consumer 150 | MyConsumer := TKafkaConsumer.Create(True); 151 | 152 | // create 0mq pusher socket 153 | My0MQContext := T0MQContext.Create(); 154 | My0MQSocket := T0MQSocket.Create(My0MQContext._Context); 155 | 156 | // setup and connect 0mqsocket 157 | // we can support PUBLISH-SUBSCRIBE pattern or PUSH-PULL pattern 158 | if My0MQSetup.socket_type = 'PUB' then begin 159 | My0MQSocket.GetSocket(ZMQ_PUB); 160 | end 161 | else begin 162 | My0MQSocket.GetSocket(ZMQ_PUSH); 163 | end; 164 | My0MQSocket.SetSockOptInteger(ZMQ_SNDHWM, My0MQSetup.hwm); 165 | My0MQSocket.SetSockOptInteger(ZMQ_SNDTIMEO, My0MQSetup.send_timeout); 166 | My0MQSocket.ConnectSocket(My0MQSetup.address); 167 | 168 | // create callback object in which I will receive kafka messages and 169 | // send it to 0mq socket 170 | MySpecificKafkaConsumer := TKafkaConsumer2ZeroMQ.Create(My0MQSocket); 171 | 172 | // start kafka consumer 173 | MyConsumer.StartConsumer(MyKafkaSetup, 174 | @MySpecificKafkaConsumer.OnKafkaMessageReceived, 175 | @MySpecificKafkaConsumer.OnKafkaMessageEOF, 176 | @MySpecificKafkaConsumer.OnKafkaMessageErr, 177 | @MySpecificKafkaConsumer.OnKafkaTick, 178 | MyMaxReadBytes); // for test receive only 128 bytes 179 | 180 | if MySpecificKafkaConsumer <> nil then FreeAndNil(MySpecificKafkaConsumer); 181 | if My0MQSocket <> nil then FreeAndNil(My0MQSocket); 182 | if My0MQContext <> nil then FreeAndNil(My0MQContext); 183 | if MyConsumer <> nil then FreeAndNil(MyConsumer); 184 | except 185 | on E: Exception do begin 186 | WriteStatus('Error: ' + E.Message); 187 | WriteStatus('ZeroMQDumpSetup: ' + ZeroMQDumpSetup(My0MQSetup)); 188 | if MySpecificKafkaConsumer <> nil then FreeAndNil(MySpecificKafkaConsumer); 189 | if My0MQSocket <> nil then FreeAndNil(My0MQSocket); 190 | if My0MQContext <> nil then FreeAndNil(My0MQContext); 191 | if MyConsumer <> nil then FreeAndNil(MyConsumer); 192 | end; 193 | end; 194 | end; 195 | 196 | procedure StartZeroMQConsumer_13(InIniFileName: String); 197 | var My0MQContext: T0MQContext; 198 | My0MQSocket: T0MQSocket; 199 | My0MQSetup: T0MQSetup; 200 | MyString: String; 201 | MyError: Integer; 202 | begin 203 | My0MQSocket := nil; 204 | 205 | try 206 | // read 0mq configuration 207 | ZeroMQReadConfiguration(InIniFileName, 'ZERO_RECEIVER', My0MQSetup); 208 | 209 | 210 | // create 0mq puller socket 211 | My0MQContext := T0MQContext.Create(); 212 | My0MQSocket := T0MQSocket.Create(My0MQContext._Context); 213 | 214 | // setup and connect 0mqsocket 215 | // we can support PUBLISH-SUBSCRIBE pattern or PUSH-PULL pattern 216 | if My0MQSetup.socket_type = 'SUB' then begin 217 | My0MQSocket.GetSocket(ZMQ_SUB); 218 | end 219 | else begin 220 | My0MQSocket.GetSocket(ZMQ_PULL); 221 | end; 222 | My0MQSocket.SetSockOptInteger(ZMQ_SNDHWM, My0MQSetup.hwm); 223 | My0MQSocket.SetSockOptInteger(ZMQ_SNDTIMEO, My0MQSetup.send_timeout); 224 | My0MQSocket.BindSocket(My0MQSetup.address); 225 | 226 | while true do begin 227 | if KeyPressed then begin // <--- CRT function to test key press 228 | if ReadKey = ^C then begin // read the key pressed 229 | WriteStatus('Ctrl-C pressed'); 230 | Break; 231 | end; 232 | end; 233 | 234 | MyString := ''; 235 | try 236 | MyError := My0MQSocket.Recv(MyString, ZMQ_DONTWAIT, 100); 237 | if MyString <> '' then begin 238 | WriteStatus('ReceivedMessage: ' + MyString); 239 | end; 240 | except 241 | on E: Exception do begin 242 | WriteStatus('Error: ' + E.Message); 243 | end; 244 | end; 245 | end; 246 | 247 | if My0MQSocket <> nil then FreeAndNil(My0MQSocket); 248 | if My0MQContext <> nil then FreeAndNil(My0MQContext); 249 | except 250 | on E: Exception do begin 251 | WriteStatus('Error: ' + E.Message); 252 | WriteStatus('ZeroMQDumpSetup: ' + ZeroMQDumpSetup(My0MQSetup)); 253 | if My0MQSocket <> nil then FreeAndNil(My0MQSocket); 254 | if My0MQContext <> nil then FreeAndNil(My0MQContext); 255 | end; 256 | end; 257 | end; 258 | 259 | 260 | end. 261 | 262 | -------------------------------------------------------------------------------- /libgcc_s_dw2-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/libgcc_s_dw2-1.dll -------------------------------------------------------------------------------- /librdkafka.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/librdkafka.dll -------------------------------------------------------------------------------- /librdkafkacpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/librdkafkacpp.dll -------------------------------------------------------------------------------- /libsodium-18.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/libsodium-18.dll -------------------------------------------------------------------------------- /libstdc++-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/libstdc++-6.dll -------------------------------------------------------------------------------- /libwinpthread-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/libwinpthread-1.dll -------------------------------------------------------------------------------- /libzmq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/libzmq.dll -------------------------------------------------------------------------------- /msgqueue/nanomsgclass.pas: -------------------------------------------------------------------------------- 1 | unit NanoMsgClass; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | interface 6 | 7 | uses 8 | Classes, SysUtils, 9 | IniFiles, 10 | 11 | nano, ctypes; 12 | 13 | type 14 | TNanoMsgSetup = record 15 | address: string; // example is tcp://172.17.41.208:5558 16 | hwm: integer; // high water mark 17 | send_timeout: integer; // send timeout 18 | recv_timeout: integer; // receiving timeout 19 | socket_type: string; // PUB, SUB, PUSH, PULL ... 20 | end; 21 | 22 | 23 | { ENanoMsgError } 24 | // Error nadling 25 | // Methods that create objects return NULL if they fail. 26 | // Methods that process data may return the number of bytes processed, or -1 on an error or failure. 27 | // Other methods return 0 on success and -1 on an error or failure. 28 | // The error code is provided in errno or zmq_errno(). 29 | // A descriptive error text for logging is provided by zmq_strerror(). 30 | 31 | 32 | ENanoMsgError = class(Exception) 33 | public 34 | _ErrNo: Integer; 35 | _ErrMsg: String; 36 | constructor Create(InErrNo: Integer; InErrMsg: String); 37 | destructor Destroy; override; 38 | end; 39 | 40 | { TNanoMsgSocket } 41 | 42 | TNanoMsgSocket = class 43 | _Socket: Integer; 44 | _SocketType: cint; 45 | _BindString: String; 46 | _ConnectString: String; 47 | _RecvBuffer: array[0..(65536 * 100)-1] of char; 48 | public 49 | constructor Create(); overload; 50 | destructor Destroy; override; 51 | 52 | procedure CleanUp; 53 | function GetSocket(InSocketType: cint): Integer; 54 | function BindSocket(InBindString: String): cint; 55 | function ConnectSocket(InConnectString: String): cint; 56 | function CloseSocket: cint; 57 | 58 | function Send(InBuffer: Pointer; InLen: csize_t; InFlags: cint = 0): cint; overload; 59 | function Send(InString: String): cint; 60 | function Recv(InBuffer: Pointer; InBufferSize: cint; InFlags: cint = 0): cint; overload; 61 | function Recv(var OutString: String; InFlags: cint = 0; InHowMuchMilliseconds: cint = 0): cint; overload; 62 | 63 | function SetSockOptInteger(InOption: cint; InValue: Integer; InLevel: integer = NN_SOL_SOCKET): cint; 64 | function SetSockOptInt64(InOption: cint; InValue: Int64; InLevel: integer = NN_SOL_SOCKET): cint; 65 | function SetSockOptString(InOption: cint; InValue: string; InLevel: integer = NN_SOL_SOCKET): cint; 66 | 67 | function GetSockOptInteger(InOption: cint; InLevel: integer = NN_SOL_SOCKET): Integer; 68 | function GetSockOptInt64(InOption: cint; InLevel: integer = NN_SOL_SOCKET): Int64; 69 | function GetSockOptString(InOption: cint; InLevel: integer = NN_SOL_SOCKET): String; 70 | end; 71 | 72 | var InitTNanoMsgSetup: TNanoMsgSetup = ({%H-}); 73 | 74 | function GetNanoMsgError(InErrorCode: cint): String; 75 | procedure RaiseNanoMsgError(InErrNo: Integer; 76 | InErrMsg: String); 77 | procedure NanoMsgReadConfiguration(InIniFile: TIniFile; InSection: String; var OutNanoMsgSetup: TNanoMsgSetup); overload; 78 | procedure NanoMsgReadConfiguration(InIniFileName: String; InSection: String; var OutNanoMsgSetup: TNanoMsgSetup); overload; 79 | 80 | implementation 81 | 82 | function GetNanoMsgError(InErrorCode: cint): String; 83 | var MyErrPChar: PChar; 84 | MyResult: String; 85 | begin 86 | MyResult:= ''; 87 | MyErrPChar := nn_strerror(InErrorCode); 88 | MyResult := String(MyErrPChar); 89 | Result := MyResult; 90 | end; 91 | 92 | procedure RaiseNanoMsgError(InErrNo: Integer; InErrMsg: String); 93 | begin 94 | raise ENanoMsgError.Create(InErrNo, InErrMsg); 95 | end; 96 | 97 | { ENanoMsgError } 98 | 99 | constructor ENanoMsgError.Create(InErrNo: Integer; InErrMsg: String); 100 | begin 101 | inherited Create(InErrMsg); 102 | _ErrNo := InErrNo; 103 | _ErrMsg := InErrMsg; 104 | end; 105 | 106 | destructor ENanoMsgError.Destroy; 107 | begin 108 | inherited Destroy; 109 | end; 110 | 111 | { TNanoMsgSocket } 112 | 113 | constructor TNanoMsgSocket.Create(); 114 | begin 115 | CleanUp; 116 | end; 117 | 118 | destructor TNanoMsgSocket.Destroy; 119 | begin 120 | try 121 | if _Socket >= 0 then begin 122 | CloseSocket; 123 | end; 124 | except 125 | // I dont care about error 126 | end; 127 | 128 | CleanUp; 129 | inherited Destroy; 130 | end; 131 | 132 | procedure TNanoMsgSocket.CleanUp; 133 | begin 134 | _Socket := -1; 135 | _SocketType := 0; 136 | _BindString := ''; 137 | _ConnectString := ''; 138 | end; 139 | 140 | function TNanoMsgSocket.GetSocket(InSocketType: cint): Integer; 141 | var MyResult: Integer; 142 | MyError: cint; 143 | MyErrorString: String; 144 | begin 145 | MyResult := -1; 146 | _SocketType := InSocketType; 147 | MyResult := nn_socket (AF_SP, InSocketType); 148 | if MyResult < 0 then begin 149 | MyError := nn_errno; 150 | MyErrorString := GetNanoMsgError(MyError); 151 | RaiseNanoMsgError(MyError, MyErrorString); 152 | end; 153 | _Socket := MyResult; 154 | Result := MyResult; 155 | end; 156 | 157 | function TNanoMsgSocket.BindSocket(InBindString: String): cint; 158 | var MyRC: cint; 159 | MyError: cint; 160 | MyErrorString: String; 161 | begin 162 | _BindString := InBindString; 163 | MyRC := nn_bind(_Socket, PChar(InBindString)); 164 | if MyRC = -1 then begin 165 | MyError := nn_errno(); 166 | MyErrorString := GetNanoMsgError(MyError); 167 | RaiseNanoMsgError(MyError, MyErrorString); 168 | end; 169 | Result := MyRC; 170 | end; 171 | 172 | function TNanoMsgSocket.ConnectSocket(InConnectString: String): cint; 173 | var MyRC: cint; 174 | MyError: cint; 175 | MyErrorString: String; 176 | begin 177 | _ConnectString := InConnectString; 178 | MyRC := nn_connect(_Socket, PChar(InConnectString)); 179 | if MyRC = -1 then begin 180 | MyError := nn_errno(); 181 | MyErrorString := GetNanoMsgError(MyError); 182 | RaiseNanoMsgError(MyError, MyErrorString); 183 | end; 184 | Result := MyRC; 185 | end; 186 | 187 | function TNanoMsgSocket.CloseSocket: cint; 188 | var MyRC: cint; 189 | MyError: cint; 190 | MyErrorString: String; 191 | begin 192 | MyRC := nn_close(_Socket); 193 | if MyRC = -1 then begin 194 | MyError := nn_errno(); 195 | MyErrorString := GetNanoMsgError(MyError); 196 | RaiseNanoMsgError(MyError, MyErrorString); 197 | end; 198 | CleanUp; 199 | Result := MyRC; 200 | end; 201 | 202 | function TNanoMsgSocket.Send(InBuffer: Pointer; InLen: csize_t; InFlags: cint): cint; 203 | var MyRC: cint; 204 | MyError: cint; 205 | MyErrorString: String; 206 | begin 207 | MyRC := nn_send(_Socket, InBuffer, InLen, InFlags); 208 | if MyRC = -1 then begin 209 | MyError := nn_errno(); 210 | MyErrorString := GetNanoMsgError(MyError); 211 | RaiseNanoMsgError(MyError, MyErrorString); 212 | end; 213 | Result := MyRC; 214 | end; 215 | 216 | function TNanoMsgSocket.Send(InString: String): cint; 217 | begin 218 | Result := Send(Pchar(InString), Length(InString), 0); 219 | end; 220 | 221 | function TNanoMsgSocket.Recv(InBuffer: Pointer; InBufferSize: cint; InFlags: cint): cint; 222 | var MyRC: cint; 223 | MyError: cint; 224 | MyErrorString: String; 225 | begin 226 | MyRC := nn_recv(_Socket, InBuffer, InBufferSize, InFlags); 227 | if ((MyRC = -1) and (InFlags = 0)) then begin 228 | MyError := nn_errno(); 229 | MyErrorString := GetNanoMsgError(MyError); 230 | RaiseNanoMsgError(MyError, MyErrorString); 231 | end; 232 | Result := MyRC; 233 | end; 234 | 235 | function TNanoMsgSocket.Recv(var OutString: String; InFlags: cint; 236 | InHowMuchMilliseconds: cint): cint; 237 | var MyResult: cint; 238 | begin 239 | FillChar(_RecvBuffer, SizeOf(_RecvBuffer), 0); 240 | if InFlags = NN_DONTWAIT then begin 241 | while InHowMuchMilliseconds > 0 do begin 242 | MyResult := Recv(@_RecvBuffer, SizeOf(_RecvBuffer), InFlags); 243 | if MyResult = -1 then begin 244 | if nn_errno = EAGAIN then begin 245 | InHowMuchMilliseconds := InHowMuchMilliseconds - 100; 246 | Sleep(100); 247 | end 248 | else begin 249 | break; 250 | end; 251 | end 252 | else begin 253 | Break; 254 | end; 255 | end; 256 | end 257 | else begin 258 | MyResult := Recv(@_RecvBuffer, SizeOf(_RecvBuffer), InFlags); 259 | end; 260 | OutString := _RecvBuffer; 261 | Result := MyResult; 262 | end; 263 | 264 | function TNanoMsgSocket.SetSockOptInteger(InOption: cint; InValue: Integer; 265 | InLevel: integer): cint; 266 | var MyRC: cint; 267 | MyError: cint; 268 | MyErrorString: String; 269 | begin 270 | // NN_SUB - possible levels 271 | // NN_TCP 272 | // NN_SOL_SOCKET 273 | 274 | MyRC := nn_setsockopt(_Socket, InLevel, InOption, @InValue, sizeof(InValue)); 275 | if MyRC = -1 then begin 276 | MyError := nn_errno(); 277 | MyErrorString := GetNanoMsgError(MyError); 278 | RaiseNanoMsgError(MyError, MyErrorString); 279 | end; 280 | Result := MyRC; 281 | end; 282 | 283 | function TNanoMsgSocket.SetSockOptInt64(InOption: cint; InValue: Int64; 284 | InLevel: integer): cint; 285 | var MyRC: cint; 286 | MyError: cint; 287 | MyErrorString: String; 288 | begin 289 | MyRC := nn_setsockopt(_Socket, InLevel, InOption, @InValue, sizeof(InValue)); 290 | if MyRC = -1 then begin 291 | MyError := nn_errno(); 292 | MyErrorString := GetNanoMsgError(MyError); 293 | RaiseNanoMsgError(MyError, MyErrorString); 294 | end; 295 | Result := MyRC; 296 | end; 297 | 298 | function TNanoMsgSocket.SetSockOptString(InOption: cint; InValue: string; InLevel: integer): cint; 299 | var MyRC: cint; 300 | MyError: cint; 301 | MyErrorString: String; 302 | begin 303 | // NN_SUB - possible levels 304 | // NN_TCP 305 | 306 | if Length(InValue) > 0 then begin 307 | MyRC := nn_setsockopt(_Socket, InLevel, InOption, @InValue[1], Length(InValue)); 308 | end 309 | else begin 310 | MyRC := nn_setsockopt(_Socket, InLevel, InOption, @InValue, 0); 311 | end; 312 | if MyRC = -1 then begin 313 | MyError := nn_errno(); 314 | MyErrorString := GetNanoMsgError(MyError); 315 | RaiseNanoMsgError(MyError, MyErrorString); 316 | end; 317 | Result := MyRC; 318 | end; 319 | 320 | function TNanoMsgSocket.GetSockOptInteger(InOption: cint; InLevel: integer 321 | ): Integer; 322 | var MyRC: cint; 323 | MyError: cint; 324 | MyErrorString: String; 325 | MyValue: Integer; 326 | MySize: size_t; 327 | begin 328 | MyValue := 0; 329 | MySize := SizeOf(MyValue); 330 | MyRC := nn_getsockopt(_Socket, InLevel, InOption, @MyValue, MySize); 331 | if MyRC = -1 then begin 332 | MyError := nn_errno(); 333 | MyErrorString := GetNanoMsgError(MyError); 334 | RaiseNanoMsgError(MyError, MyErrorString); 335 | end; 336 | Result := MyValue; 337 | end; 338 | 339 | function TNanoMsgSocket.GetSockOptInt64(InOption: cint; InLevel: integer 340 | ): Int64; 341 | var MyRC: cint; 342 | MyError: cint; 343 | MyErrorString: String; 344 | MyValue: Int64; 345 | MySize: size_t; 346 | begin 347 | MyValue := 0; 348 | MySize := SizeOf(MyValue); 349 | MyRC := nn_getsockopt(_Socket, InLevel, InOption, @MyValue, MySize); 350 | if MyRC = -1 then begin 351 | MyError := nn_errno(); 352 | MyErrorString := GetNanoMsgError(MyError); 353 | RaiseNanoMsgError(MyError, MyErrorString); 354 | end; 355 | Result := MyValue; 356 | end; 357 | 358 | function TNanoMsgSocket.GetSockOptString(InOption: cint; InLevel: integer 359 | ): String; 360 | var MyRC: cint; 361 | MyError: cint; 362 | MyErrorString: String; 363 | MyValue: array[0..10*1024-1] of char; 364 | MySize: DWord; 365 | begin 366 | MySize := SizeOf(MyValue); 367 | FillByte(MyValue, MySize, 0); 368 | MyRC := nn_getsockopt(_Socket, InLevel, InOption, @MyValue[0], MySize); 369 | if (MyRC = -1) then begin 370 | MyError := nn_errno(); 371 | MyErrorString := GetNanoMsgError(MyError); 372 | RaiseNanoMsgError(MyError, MyErrorString); 373 | end; 374 | Result := String(MyValue); 375 | end; 376 | 377 | procedure NanoMsgReadConfiguration(InIniFile: TIniFile; InSection: String; 378 | var OutNanoMsgSetup: TNanoMsgSetup); 379 | begin 380 | OutNanoMsgSetup := InitTNanoMsgSetup; 381 | OutNanoMsgSetup.address := InIniFile.ReadString(InSection, 'address', ''); 382 | OutNanoMsgSetup.hwm := InIniFile.ReadInteger(InSection, 'hwm', 200); 383 | OutNanoMsgSetup.send_timeout := InIniFile.ReadInteger(InSection, 'send_timeout', 0); 384 | OutNanoMsgSetup.recv_timeout := InIniFile.ReadInteger(InSection, 'recv_timeout', 0); 385 | OutNanoMsgSetup.socket_type := InIniFile.ReadString(InSection, 'socket_type', 'PULL'); 386 | end; 387 | 388 | procedure NanoMsgReadConfiguration(InIniFileName: String; InSection: String; 389 | var OutNanoMsgSetup: TNanoMsgSetup); 390 | var MyIniFile: TIniFile; 391 | begin 392 | OutNanoMsgSetup := InitTNanoMsgSetup; 393 | MyIniFile := nil; 394 | try 395 | if FileExists(InIniFileName) then begin 396 | MyIniFile := TIniFile.Create(InIniFileName); 397 | NanoMsgReadConfiguration(MyIniFile, InSection, OutNanoMsgSetup); 398 | if MyIniFile <> nil then begin 399 | FreeAndNil(MyIniFile); 400 | end; 401 | end; 402 | except 403 | if MyIniFile <> nil then begin 404 | FreeAndNil(MyIniFile); 405 | end; 406 | end; 407 | end; 408 | 409 | 410 | end. 411 | 412 | -------------------------------------------------------------------------------- /msgqueue/zmqclass.pas: -------------------------------------------------------------------------------- 1 | unit ZMQClass; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | interface 6 | 7 | uses 8 | Classes, SysUtils, 9 | IniFiles, 10 | 11 | zmq, ctypes; 12 | 13 | type 14 | T0MQSetup = record 15 | address: string; // example is tcp://172.17.41.208:5558 16 | hwm: integer; // high water mark 17 | send_timeout: integer; // send timeout 18 | recv_timeout: integer; // receiving timeout 19 | socket_type: string; // PUB, SUB, PUSH, PULL ... 20 | end; 21 | 22 | 23 | { E0MQError } 24 | // Error nadling 25 | // Methods that create objects return NULL if they fail. 26 | // Methods that process data may return the number of bytes processed, or -1 on an error or failure. 27 | // Other methods return 0 on success and -1 on an error or failure. 28 | // The error code is provided in errno or zmq_errno(). 29 | // A descriptive error text for logging is provided by zmq_strerror(). 30 | 31 | 32 | E0MQError = class(Exception) 33 | public 34 | _ErrNo: Integer; 35 | _ErrMsg: String; 36 | constructor Create(InErrNo: Integer; InErrMsg: String); 37 | destructor Destroy; override; 38 | end; 39 | 40 | { T0MQContext } 41 | 42 | T0MQContext = class 43 | _Context: Pointer; 44 | public 45 | constructor Create; 46 | destructor Destroy; override; 47 | function GetContext: Pointer; 48 | end; 49 | 50 | { T0MQSocket } 51 | 52 | T0MQSocket = class 53 | _Context: Pointer; 54 | _Socket: Pointer; 55 | _SocketType: cint; 56 | _BindString: String; 57 | _ConnectString: String; 58 | _RecvBuffer: array[0..(65536 * 100)-1] of char; 59 | public 60 | constructor Create(InContext: Pointer); overload; 61 | constructor Create(InContext: T0MQContext); overload; 62 | destructor Destroy; override; 63 | 64 | procedure CleanUp; 65 | function GetSocket(InSocketType: cint): Pointer; 66 | function BindSocket(InBindString: String): cint; 67 | function ConnectSocket(InConnectString: String): cint; 68 | function CloseSocket: cint; 69 | 70 | function Send(InBuffer: Pointer; InLen: csize_t; InFlags: cint = 0): cint; overload; 71 | function Send(var InString: String): cint; 72 | function Recv(InBuffer: Pointer; InBufferSize: cint; InFlags: cint = 0): cint; overload; 73 | function Recv(var OutString: String; InFlags: cint = 0; InHowMuchMilliseconds: cint = 0): cint; overload; 74 | 75 | function SetSockOptInteger(InOption: cint; InValue: Integer): cint; 76 | function SetSockOptInt64(InOption: cint; InValue: Int64): cint; 77 | 78 | function GetSockOptInteger(InOption: cint): Integer; 79 | function GetSockOptInt64(InOption: cint): Int64; 80 | end; 81 | 82 | var InitT0MQSetup: T0MQSetup = ({%H-}); 83 | 84 | function Get0MQError(InErrorCode: cint): String; 85 | procedure Raise0MQError(InErrNo: Integer; 86 | InErrMsg: String); 87 | procedure ZeroMQReadConfiguration(InIniFile: TIniFile; InSection: String; var Out0MQSetup: T0MQSetup); overload; 88 | procedure ZeroMQReadConfiguration(InIniFileName: String; InSection: String; var Out0MQSetup: T0MQSetup); overload; 89 | function ZeroMQDumpSetup(var In0MQSetup: T0MQSetup): String; 90 | 91 | implementation 92 | 93 | function Get0MQError(InErrorCode: cint): String; 94 | var MyErrPChar: PChar; 95 | MyResult: String; 96 | begin 97 | MyResult:= ''; 98 | MyErrPChar := zmq_strerror(InErrorCode); 99 | MyResult := String(MyErrPChar); 100 | Result := MyResult; 101 | end; 102 | 103 | procedure Raise0MQError(InErrNo: Integer; InErrMsg: String); 104 | begin 105 | raise E0MQError.Create(InErrNo, InErrMsg); 106 | end; 107 | 108 | { T0MQContext } 109 | 110 | constructor T0MQContext.Create; 111 | var MyError: cint; 112 | MyErrorString: String; 113 | begin 114 | _Context := nil; 115 | _Context := zmq.zmq_ctx_new(); 116 | if _Context = nil then begin 117 | MyError := zmq_errno(); 118 | MyErrorString := Get0MQError(MyError); 119 | Raise0MQError(MyError, MyErrorString); 120 | end; 121 | end; 122 | 123 | destructor T0MQContext.Destroy; 124 | var MyRC: cint; 125 | MyError: cint; 126 | MyErrorString: String; 127 | begin 128 | MyRC := zmq_ctx_destroy (_Context); 129 | if MyRC = -1 then begin 130 | MyError := zmq_errno(); 131 | MyErrorString := Get0MQError(MyError); 132 | Raise0MQError(MyError, MyErrorString); 133 | end; 134 | 135 | inherited Destroy; 136 | end; 137 | 138 | function T0MQContext.GetContext: Pointer; 139 | begin 140 | Result := _Context; 141 | end; 142 | 143 | { E0MQError } 144 | 145 | constructor E0MQError.Create(InErrNo: Integer; InErrMsg: String); 146 | begin 147 | inherited Create(InErrMsg); 148 | _ErrNo := InErrNo; 149 | _ErrMsg := InErrMsg; 150 | end; 151 | 152 | destructor E0MQError.Destroy; 153 | begin 154 | inherited Destroy; 155 | end; 156 | 157 | { T0MQSocket } 158 | 159 | constructor T0MQSocket.Create(InContext: Pointer); 160 | begin 161 | CleanUp; 162 | _Context := InContext; 163 | end; 164 | 165 | constructor T0MQSocket.Create(InContext: T0MQContext); 166 | begin 167 | _Context := InContext.GetContext; 168 | end; 169 | 170 | destructor T0MQSocket.Destroy; 171 | begin 172 | try 173 | if _Socket <> nil then begin 174 | CloseSocket; 175 | end; 176 | except 177 | // I dont care about error 178 | end; 179 | 180 | CleanUp; 181 | inherited Destroy; 182 | end; 183 | 184 | procedure T0MQSocket.CleanUp; 185 | begin 186 | _Context := nil; 187 | _Socket := nil; 188 | _SocketType := 0; 189 | _BindString := ''; 190 | _ConnectString := ''; 191 | end; 192 | 193 | function T0MQSocket.GetSocket(InSocketType: cint): Pointer; 194 | var MyResult: Pointer; 195 | MyError: cint; 196 | MyErrorString: String; 197 | begin 198 | MyResult := nil; 199 | _SocketType := InSocketType; 200 | MyResult := zmq_socket (_Context, InSocketType); 201 | if MyResult = nil then begin 202 | MyError := zmq_errno(); 203 | MyErrorString := Get0MQError(MyError); 204 | Raise0MQError(MyError, MyErrorString); 205 | end; 206 | _Socket := MyResult; 207 | Result := MyResult; 208 | end; 209 | 210 | function T0MQSocket.BindSocket(InBindString: String): cint; 211 | var MyRC: cint; 212 | MyError: cint; 213 | MyErrorString: String; 214 | begin 215 | _BindString := InBindString; 216 | MyRC := zmq_bind(_Socket, PChar(InBindString)); 217 | if MyRC = -1 then begin 218 | MyError := zmq_errno(); 219 | MyErrorString := Get0MQError(MyError); 220 | Raise0MQError(MyError, MyErrorString); 221 | end; 222 | Result := MyRC; 223 | end; 224 | 225 | function T0MQSocket.ConnectSocket(InConnectString: String): cint; 226 | var MyRC: cint; 227 | MyError: cint; 228 | MyErrorString: String; 229 | begin 230 | _ConnectString := InConnectString; 231 | MyRC := zmq_connect(_Socket, PChar(InConnectString)); 232 | if MyRC = -1 then begin 233 | MyError := zmq_errno(); 234 | MyErrorString := Get0MQError(MyError); 235 | Raise0MQError(MyError, MyErrorString); 236 | end; 237 | Result := MyRC; 238 | end; 239 | 240 | function T0MQSocket.CloseSocket: cint; 241 | var MyRC: cint; 242 | MyError: cint; 243 | MyErrorString: String; 244 | begin 245 | MyRC := zmq_close(_Socket); 246 | if MyRC = -1 then begin 247 | MyError := zmq_errno(); 248 | MyErrorString := Get0MQError(MyError); 249 | Raise0MQError(MyError, MyErrorString); 250 | end; 251 | CleanUp; 252 | Result := MyRC; 253 | end; 254 | 255 | function T0MQSocket.Send(InBuffer: Pointer; InLen: csize_t; InFlags: cint): cint; 256 | var MyRC: cint; 257 | MyError: cint; 258 | MyErrorString: String; 259 | begin 260 | MyRC := zmq_send(_Socket, InBuffer, InLen, InFlags); 261 | if MyRC = -1 then begin 262 | MyError := zmq_errno(); 263 | MyErrorString := Get0MQError(MyError); 264 | Raise0MQError(MyError, MyErrorString); 265 | end; 266 | Result := MyRC; 267 | end; 268 | 269 | function T0MQSocket.Send(var InString: String): cint; 270 | begin 271 | Result := Send(Pchar(InString), Length(InString), 0); 272 | end; 273 | 274 | function T0MQSocket.Recv(InBuffer: Pointer; InBufferSize: cint; InFlags: cint): cint; 275 | var MyRC: cint; 276 | MyError: cint; 277 | MyErrorString: String; 278 | begin 279 | MyRC := zmq_recv(_Socket, InBuffer, InBufferSize, InFlags); 280 | if ((MyRC = -1) and (InFlags = 0)) then begin 281 | MyError := zmq_errno(); 282 | MyErrorString := Get0MQError(MyError); 283 | Raise0MQError(MyError, MyErrorString); 284 | end; 285 | Result := MyRC; 286 | end; 287 | 288 | function T0MQSocket.Recv(var OutString: String; InFlags: cint; 289 | InHowMuchMilliseconds: cint): cint; 290 | var MyResult: cint; 291 | begin 292 | FillChar(_RecvBuffer, SizeOf(_RecvBuffer), 0); 293 | if InFlags = ZMQ_DONTWAIT then begin 294 | while InHowMuchMilliseconds > 0 do begin 295 | MyResult := Recv(@_RecvBuffer, SizeOf(_RecvBuffer), InFlags); 296 | if MyResult = -1 then begin 297 | if zmq_errno = ZMQ_EAGAIN then begin 298 | InHowMuchMilliseconds := InHowMuchMilliseconds - 100; 299 | Sleep(100); 300 | end 301 | else begin 302 | break; 303 | end; 304 | end 305 | else begin 306 | Break; 307 | end; 308 | end; 309 | end 310 | else begin 311 | MyResult := Recv(@_RecvBuffer, SizeOf(_RecvBuffer), InFlags); 312 | end; 313 | OutString := _RecvBuffer; 314 | Result := MyResult; 315 | end; 316 | 317 | function T0MQSocket.SetSockOptInteger(InOption: cint; InValue: Integer): cint; 318 | var MyRC: cint; 319 | MyError: cint; 320 | MyErrorString: String; 321 | begin 322 | MyRC := zmq_setsockopt(_Socket, InOption, @InValue, sizeof(InValue)); 323 | if MyRC = -1 then begin 324 | MyError := zmq_errno(); 325 | MyErrorString := Get0MQError(MyError); 326 | Raise0MQError(MyError, MyErrorString); 327 | end; 328 | Result := MyRC; 329 | end; 330 | 331 | function T0MQSocket.SetSockOptInt64(InOption: cint; InValue: Int64): cint; 332 | var MyRC: cint; 333 | MyError: cint; 334 | MyErrorString: String; 335 | begin 336 | MyRC := zmq_setsockopt(_Socket, InOption, @InValue, sizeof(InValue)); 337 | if MyRC = -1 then begin 338 | MyError := zmq_errno(); 339 | MyErrorString := Get0MQError(MyError); 340 | Raise0MQError(MyError, MyErrorString); 341 | end; 342 | Result := MyRC; 343 | end; 344 | 345 | function T0MQSocket.GetSockOptInteger(InOption: cint): Integer; 346 | var MyRC: cint; 347 | MyError: cint; 348 | MyErrorString: String; 349 | MyValue: Integer; 350 | MySize: size_t; 351 | begin 352 | MyValue := 0; 353 | MySize := SizeOf(MyValue); 354 | MyRC := zmq_getsockopt(_Socket, InOption, @MyValue, @MySize); 355 | if MyRC = -1 then begin 356 | MyError := zmq_errno(); 357 | MyErrorString := Get0MQError(MyError); 358 | Raise0MQError(MyError, MyErrorString); 359 | end; 360 | Result := MyValue; 361 | end; 362 | 363 | function T0MQSocket.GetSockOptInt64(InOption: cint): Int64; 364 | var MyRC: cint; 365 | MyError: cint; 366 | MyErrorString: String; 367 | MyValue: Int64; 368 | MySize: size_t; 369 | begin 370 | MyValue := 0; 371 | MySize := SizeOf(MyValue); 372 | MyRC := zmq_getsockopt(_Socket, InOption, @MyValue, @MySize); 373 | if MyRC = -1 then begin 374 | MyError := zmq_errno(); 375 | MyErrorString := Get0MQError(MyError); 376 | Raise0MQError(MyError, MyErrorString); 377 | end; 378 | Result := MyValue; 379 | end; 380 | 381 | procedure ZeroMQReadConfiguration(InIniFile: TIniFile; InSection: String; 382 | var Out0MQSetup: T0MQSetup); 383 | begin 384 | Out0MQSetup := InitT0MQSetup; 385 | Out0MQSetup.address := InIniFile.ReadString(InSection, 'address', ''); 386 | Out0MQSetup.hwm := InIniFile.ReadInteger(InSection, 'hwm', 200); 387 | Out0MQSetup.send_timeout := InIniFile.ReadInteger(InSection, 'send_timeout', 0); 388 | Out0MQSetup.recv_timeout := InIniFile.ReadInteger(InSection, 'recv_timeout', 0); 389 | Out0MQSetup.socket_type := InIniFile.ReadString(InSection, 'socket_type', 'PULL'); 390 | end; 391 | 392 | procedure ZeroMQReadConfiguration(InIniFileName: String; InSection: String; 393 | var Out0MQSetup: T0MQSetup); 394 | var MyIniFile: TIniFile; 395 | begin 396 | Out0MQSetup := InitT0MQSetup; 397 | MyIniFile := nil; 398 | try 399 | if FileExists(InIniFileName) then begin 400 | MyIniFile := TIniFile.Create(InIniFileName); 401 | ZeroMQReadConfiguration(MyIniFile, InSection, Out0MQSetup); 402 | if MyIniFile <> nil then begin 403 | FreeAndNil(MyIniFile); 404 | end; 405 | end; 406 | except 407 | if MyIniFile <> nil then begin 408 | FreeAndNil(MyIniFile); 409 | end; 410 | end; 411 | end; 412 | 413 | function ZeroMQDumpSetup(var In0MQSetup: T0MQSetup): String; 414 | begin 415 | Result := Format('address=%s' + #13#10 + 416 | 'hwm=%d' + #13#10 + 417 | 'recv_timeout=%d' + #13#10 + 418 | 'end_timeout=%d' + #13#10 + 419 | 'socket_type=%s', 420 | [ 421 | In0MQSetup.address, 422 | In0MQSetup.hwm, 423 | In0MQSetup.recv_timeout, 424 | In0MQSetup.send_timeout, 425 | In0MQSetup.socket_type 426 | ]); 427 | end; 428 | 429 | 430 | end. 431 | 432 | -------------------------------------------------------------------------------- /msvcr120.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/msvcr120.dll -------------------------------------------------------------------------------- /nanomsgclass.pas: -------------------------------------------------------------------------------- 1 | unit NanoMsgClass; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | interface 6 | 7 | uses 8 | Classes, SysUtils, 9 | IniFiles, 10 | 11 | nano, ctypes; 12 | 13 | type 14 | TNanoMsgSetup = record 15 | address: string; // example is tcp://172.17.41.208:5558 16 | hwm: integer; // high water mark 17 | send_timeout: integer; // send timeout 18 | recv_timeout: integer; // receiving timeout 19 | socket_type: string; // PUB, SUB, PUSH, PULL ... 20 | end; 21 | 22 | 23 | { ENanoMsgError } 24 | // Error nadling 25 | // Methods that create objects return NULL if they fail. 26 | // Methods that process data may return the number of bytes processed, or -1 on an error or failure. 27 | // Other methods return 0 on success and -1 on an error or failure. 28 | // The error code is provided in errno or zmq_errno(). 29 | // A descriptive error text for logging is provided by zmq_strerror(). 30 | 31 | 32 | ENanoMsgError = class(Exception) 33 | public 34 | _ErrNo: Integer; 35 | _ErrMsg: String; 36 | constructor Create(InErrNo: Integer; InErrMsg: String); 37 | destructor Destroy; override; 38 | end; 39 | 40 | { TNanoMsgSocket } 41 | 42 | TNanoMsgSocket = class 43 | _Socket: Integer; 44 | _SocketType: cint; 45 | _BindString: String; 46 | _ConnectString: String; 47 | _RecvBuffer: array[0..(65536 * 100)-1] of char; 48 | public 49 | constructor Create(); overload; 50 | destructor Destroy; override; 51 | 52 | procedure CleanUp; 53 | function GetSocket(InSocketType: cint): Integer; 54 | function BindSocket(InBindString: String): cint; 55 | function ConnectSocket(InConnectString: String): cint; 56 | function CloseSocket: cint; 57 | 58 | function Send(InBuffer: Pointer; InLen: csize_t; InFlags: cint = 0): cint; overload; 59 | function Send(InString: String): cint; 60 | function Recv(InBuffer: Pointer; InBufferSize: cint; InFlags: cint = 0): cint; overload; 61 | function Recv(var OutString: String; InFlags: cint = 0; InHowMuchMilliseconds: cint = 0): cint; overload; 62 | 63 | function SetSockOptInteger(InOption: cint; InValue: Integer; InLevel: integer = NN_SOL_SOCKET): cint; 64 | function SetSockOptInt64(InOption: cint; InValue: Int64; InLevel: integer = NN_SOL_SOCKET): cint; 65 | function SetSockOptString(InOption: cint; InValue: string; InLevel: integer = NN_SOL_SOCKET): cint; 66 | 67 | function GetSockOptInteger(InOption: cint; InLevel: integer = NN_SOL_SOCKET): Integer; 68 | function GetSockOptInt64(InOption: cint; InLevel: integer = NN_SOL_SOCKET): Int64; 69 | function GetSockOptString(InOption: cint; InLevel: integer = NN_SOL_SOCKET): String; 70 | end; 71 | 72 | var InitTNanoMsgSetup: TNanoMsgSetup = ({%H-}); 73 | 74 | function GetNanoMsgError(InErrorCode: cint): String; 75 | procedure RaiseNanoMsgError(InErrNo: Integer; 76 | InErrMsg: String); 77 | procedure NanoMsgReadConfiguration(InIniFile: TIniFile; InSection: String; var OutNanoMsgSetup: TNanoMsgSetup); overload; 78 | procedure NanoMsgReadConfiguration(InIniFileName: String; InSection: String; var OutNanoMsgSetup: TNanoMsgSetup); overload; 79 | 80 | implementation 81 | 82 | function GetNanoMsgError(InErrorCode: cint): String; 83 | var MyErrPChar: PChar; 84 | MyResult: String; 85 | begin 86 | MyResult:= ''; 87 | MyErrPChar := nn_strerror(InErrorCode); 88 | MyResult := String(MyErrPChar); 89 | Result := MyResult; 90 | end; 91 | 92 | procedure RaiseNanoMsgError(InErrNo: Integer; InErrMsg: String); 93 | begin 94 | raise ENanoMsgError.Create(InErrNo, InErrMsg); 95 | end; 96 | 97 | { ENanoMsgError } 98 | 99 | constructor ENanoMsgError.Create(InErrNo: Integer; InErrMsg: String); 100 | begin 101 | inherited Create(InErrMsg); 102 | _ErrNo := InErrNo; 103 | _ErrMsg := InErrMsg; 104 | end; 105 | 106 | destructor ENanoMsgError.Destroy; 107 | begin 108 | inherited Destroy; 109 | end; 110 | 111 | { TNanoMsgSocket } 112 | 113 | constructor TNanoMsgSocket.Create(); 114 | begin 115 | CleanUp; 116 | end; 117 | 118 | destructor TNanoMsgSocket.Destroy; 119 | begin 120 | try 121 | if _Socket >= 0 then begin 122 | CloseSocket; 123 | end; 124 | except 125 | // I dont care about error 126 | end; 127 | 128 | CleanUp; 129 | inherited Destroy; 130 | end; 131 | 132 | procedure TNanoMsgSocket.CleanUp; 133 | begin 134 | _Socket := -1; 135 | _SocketType := 0; 136 | _BindString := ''; 137 | _ConnectString := ''; 138 | end; 139 | 140 | function TNanoMsgSocket.GetSocket(InSocketType: cint): Integer; 141 | var MyResult: Integer; 142 | MyError: cint; 143 | MyErrorString: String; 144 | begin 145 | MyResult := -1; 146 | _SocketType := InSocketType; 147 | MyResult := nn_socket (AF_SP, InSocketType); 148 | if MyResult < 0 then begin 149 | MyError := nn_errno; 150 | MyErrorString := GetNanoMsgError(MyError); 151 | RaiseNanoMsgError(MyError, MyErrorString); 152 | end; 153 | _Socket := MyResult; 154 | Result := MyResult; 155 | end; 156 | 157 | function TNanoMsgSocket.BindSocket(InBindString: String): cint; 158 | var MyRC: cint; 159 | MyError: cint; 160 | MyErrorString: String; 161 | begin 162 | _BindString := InBindString; 163 | MyRC := nn_bind(_Socket, PChar(InBindString)); 164 | if MyRC = -1 then begin 165 | MyError := nn_errno(); 166 | MyErrorString := GetNanoMsgError(MyError); 167 | RaiseNanoMsgError(MyError, MyErrorString); 168 | end; 169 | Result := MyRC; 170 | end; 171 | 172 | function TNanoMsgSocket.ConnectSocket(InConnectString: String): cint; 173 | var MyRC: cint; 174 | MyError: cint; 175 | MyErrorString: String; 176 | begin 177 | _ConnectString := InConnectString; 178 | MyRC := nn_connect(_Socket, PChar(InConnectString)); 179 | if MyRC = -1 then begin 180 | MyError := nn_errno(); 181 | MyErrorString := GetNanoMsgError(MyError); 182 | RaiseNanoMsgError(MyError, MyErrorString); 183 | end; 184 | Result := MyRC; 185 | end; 186 | 187 | function TNanoMsgSocket.CloseSocket: cint; 188 | var MyRC: cint; 189 | MyError: cint; 190 | MyErrorString: String; 191 | begin 192 | MyRC := nn_close(_Socket); 193 | if MyRC = -1 then begin 194 | MyError := nn_errno(); 195 | MyErrorString := GetNanoMsgError(MyError); 196 | RaiseNanoMsgError(MyError, MyErrorString); 197 | end; 198 | CleanUp; 199 | Result := MyRC; 200 | end; 201 | 202 | function TNanoMsgSocket.Send(InBuffer: Pointer; InLen: csize_t; InFlags: cint): cint; 203 | var MyRC: cint; 204 | MyError: cint; 205 | MyErrorString: String; 206 | begin 207 | MyRC := nn_send(_Socket, InBuffer, InLen, InFlags); 208 | if MyRC = -1 then begin 209 | MyError := nn_errno(); 210 | MyErrorString := GetNanoMsgError(MyError); 211 | RaiseNanoMsgError(MyError, MyErrorString); 212 | end; 213 | Result := MyRC; 214 | end; 215 | 216 | function TNanoMsgSocket.Send(InString: String): cint; 217 | begin 218 | Result := Send(Pchar(InString), Length(InString), 0); 219 | end; 220 | 221 | function TNanoMsgSocket.Recv(InBuffer: Pointer; InBufferSize: cint; InFlags: cint): cint; 222 | var MyRC: cint; 223 | MyError: cint; 224 | MyErrorString: String; 225 | begin 226 | MyRC := nn_recv(_Socket, InBuffer, InBufferSize, InFlags); 227 | if ((MyRC = -1) and (InFlags = 0)) then begin 228 | MyError := nn_errno(); 229 | MyErrorString := GetNanoMsgError(MyError); 230 | RaiseNanoMsgError(MyError, MyErrorString); 231 | end; 232 | Result := MyRC; 233 | end; 234 | 235 | function TNanoMsgSocket.Recv(var OutString: String; InFlags: cint; 236 | InHowMuchMilliseconds: cint): cint; 237 | var MyResult: cint; 238 | begin 239 | FillChar(_RecvBuffer, SizeOf(_RecvBuffer), 0); 240 | if InFlags = NN_DONTWAIT then begin 241 | while InHowMuchMilliseconds > 0 do begin 242 | MyResult := Recv(@_RecvBuffer, SizeOf(_RecvBuffer), InFlags); 243 | if MyResult = -1 then begin 244 | if nn_errno = EAGAIN then begin 245 | InHowMuchMilliseconds := InHowMuchMilliseconds - 100; 246 | Sleep(100); 247 | end 248 | else begin 249 | break; 250 | end; 251 | end 252 | else begin 253 | Break; 254 | end; 255 | end; 256 | end 257 | else begin 258 | MyResult := Recv(@_RecvBuffer, SizeOf(_RecvBuffer), InFlags); 259 | end; 260 | OutString := _RecvBuffer; 261 | Result := MyResult; 262 | end; 263 | 264 | function TNanoMsgSocket.SetSockOptInteger(InOption: cint; InValue: Integer; 265 | InLevel: integer): cint; 266 | var MyRC: cint; 267 | MyError: cint; 268 | MyErrorString: String; 269 | begin 270 | // NN_SUB - possible levels 271 | // NN_TCP 272 | // NN_SOL_SOCKET 273 | 274 | MyRC := nn_setsockopt(_Socket, InLevel, InOption, @InValue, sizeof(InValue)); 275 | if MyRC = -1 then begin 276 | MyError := nn_errno(); 277 | MyErrorString := GetNanoMsgError(MyError); 278 | RaiseNanoMsgError(MyError, MyErrorString); 279 | end; 280 | Result := MyRC; 281 | end; 282 | 283 | function TNanoMsgSocket.SetSockOptInt64(InOption: cint; InValue: Int64; 284 | InLevel: integer): cint; 285 | var MyRC: cint; 286 | MyError: cint; 287 | MyErrorString: String; 288 | begin 289 | MyRC := nn_setsockopt(_Socket, InLevel, InOption, @InValue, sizeof(InValue)); 290 | if MyRC = -1 then begin 291 | MyError := nn_errno(); 292 | MyErrorString := GetNanoMsgError(MyError); 293 | RaiseNanoMsgError(MyError, MyErrorString); 294 | end; 295 | Result := MyRC; 296 | end; 297 | 298 | function TNanoMsgSocket.SetSockOptString(InOption: cint; InValue: string; InLevel: integer): cint; 299 | var MyRC: cint; 300 | MyError: cint; 301 | MyErrorString: String; 302 | begin 303 | // NN_SUB - possible levels 304 | // NN_TCP 305 | 306 | if Length(InValue) > 0 then begin 307 | MyRC := nn_setsockopt(_Socket, InLevel, InOption, @InValue[1], Length(InValue)); 308 | end 309 | else begin 310 | MyRC := nn_setsockopt(_Socket, InLevel, InOption, @InValue, 0); 311 | end; 312 | if MyRC = -1 then begin 313 | MyError := nn_errno(); 314 | MyErrorString := GetNanoMsgError(MyError); 315 | RaiseNanoMsgError(MyError, MyErrorString); 316 | end; 317 | Result := MyRC; 318 | end; 319 | 320 | function TNanoMsgSocket.GetSockOptInteger(InOption: cint; InLevel: integer 321 | ): Integer; 322 | var MyRC: cint; 323 | MyError: cint; 324 | MyErrorString: String; 325 | MyValue: Integer; 326 | MySize: size_t; 327 | begin 328 | MyValue := 0; 329 | MySize := SizeOf(MyValue); 330 | MyRC := nn_getsockopt(_Socket, InLevel, InOption, @MyValue, MySize); 331 | if MyRC = -1 then begin 332 | MyError := nn_errno(); 333 | MyErrorString := GetNanoMsgError(MyError); 334 | RaiseNanoMsgError(MyError, MyErrorString); 335 | end; 336 | Result := MyValue; 337 | end; 338 | 339 | function TNanoMsgSocket.GetSockOptInt64(InOption: cint; InLevel: integer 340 | ): Int64; 341 | var MyRC: cint; 342 | MyError: cint; 343 | MyErrorString: String; 344 | MyValue: Int64; 345 | MySize: size_t; 346 | begin 347 | MyValue := 0; 348 | MySize := SizeOf(MyValue); 349 | MyRC := nn_getsockopt(_Socket, InLevel, InOption, @MyValue, MySize); 350 | if MyRC = -1 then begin 351 | MyError := nn_errno(); 352 | MyErrorString := GetNanoMsgError(MyError); 353 | RaiseNanoMsgError(MyError, MyErrorString); 354 | end; 355 | Result := MyValue; 356 | end; 357 | 358 | function TNanoMsgSocket.GetSockOptString(InOption: cint; InLevel: integer 359 | ): String; 360 | var MyRC: cint; 361 | MyError: cint; 362 | MyErrorString: String; 363 | MyValue: array[0..10*1024-1] of char; 364 | MySize: DWord; 365 | begin 366 | MySize := SizeOf(MyValue); 367 | FillByte(MyValue, MySize, 0); 368 | MyRC := nn_getsockopt(_Socket, InLevel, InOption, @MyValue[0], MySize); 369 | if (MyRC = -1) then begin 370 | MyError := nn_errno(); 371 | MyErrorString := GetNanoMsgError(MyError); 372 | RaiseNanoMsgError(MyError, MyErrorString); 373 | end; 374 | Result := String(MyValue); 375 | end; 376 | 377 | procedure NanoMsgReadConfiguration(InIniFile: TIniFile; InSection: String; 378 | var OutNanoMsgSetup: TNanoMsgSetup); 379 | begin 380 | OutNanoMsgSetup := InitTNanoMsgSetup; 381 | OutNanoMsgSetup.address := InIniFile.ReadString(InSection, 'address', ''); 382 | OutNanoMsgSetup.hwm := InIniFile.ReadInteger(InSection, 'hwm', 200); 383 | OutNanoMsgSetup.send_timeout := InIniFile.ReadInteger(InSection, 'send_timeout', 0); 384 | OutNanoMsgSetup.recv_timeout := InIniFile.ReadInteger(InSection, 'recv_timeout', 0); 385 | OutNanoMsgSetup.socket_type := InIniFile.ReadString(InSection, 'socket_type', 'PULL'); 386 | end; 387 | 388 | procedure NanoMsgReadConfiguration(InIniFileName: String; InSection: String; 389 | var OutNanoMsgSetup: TNanoMsgSetup); 390 | var MyIniFile: TIniFile; 391 | begin 392 | OutNanoMsgSetup := InitTNanoMsgSetup; 393 | MyIniFile := nil; 394 | try 395 | if FileExists(InIniFileName) then begin 396 | MyIniFile := TIniFile.Create(InIniFileName); 397 | NanoMsgReadConfiguration(MyIniFile, InSection, OutNanoMsgSetup); 398 | if MyIniFile <> nil then begin 399 | FreeAndNil(MyIniFile); 400 | end; 401 | end; 402 | except 403 | if MyIniFile <> nil then begin 404 | FreeAndNil(MyIniFile); 405 | end; 406 | end; 407 | end; 408 | 409 | 410 | end. 411 | 412 | -------------------------------------------------------------------------------- /win7-x64.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64.zip -------------------------------------------------------------------------------- /win7-x64/native/KafkaGate.ini: -------------------------------------------------------------------------------- 1 | [kafka_producer] 2 | broker=10.16.14.71:9092 3 | topic=sportfeedxml_2 4 | conf_section=kafka_producer_conf 5 | topic_section=kafka_producer_topic 6 | 7 | [kafka_producer_conf] 8 | message.max.bytes=1500000 9 | socket.keepalive.enable=true 10 | socket.blocking.max.ms=1 11 | queue.buffering.max.messages=2 12 | queue.buffering.max.ms=0 13 | message.send.max.retries=10 14 | retry.backoff.ms=100 15 | compression.codec=none 16 | batch.num.messages=1 17 | delivery.report.only.error=true 18 | socket.nagle.disable=true 19 | 20 | [kafka_producer_topic] 21 | offset.store.method=broker 22 | 23 | 24 | [kafka_consumer] 25 | broker=10.16.14.71:9092 26 | topic=sportfeedxml_2 27 | conf_section=kafka_consumer_conf 28 | topic_section=kafka_consumer_topic 29 | 30 | [kafka_consumer_conf] 31 | group.id=sbofferdispatcher_live17 32 | socket.keepalive.enable=true 33 | socket.blocking.max.ms=1 34 | #socket.blocking.max.ms=1 35 | socket.nagle.disable=true 36 | queued.min.messages=100000 37 | queued.max.messages.kbytes=1000000000 38 | fetch.wait.max.ms=0 39 | #fetch.message.max.bytes=1024 40 | #fetch.message.max.bytes=1000000000 41 | fetch.min.bytes=1 42 | fetch.wait.max.ms=1 43 | fetch.error.backoff.ms=1 44 | message.max.bytes=100000000 45 | auto.commit.interval.ms=5000 46 | enable.auto.offset.store=true 47 | auto.offset.reset=latest 48 | #enable.partition.eof=false 49 | receive.message.max.bytes=1000000000 50 | api.version.request=false 51 | 52 | [kafka_consumer_topic] 53 | offset.store.method=broker 54 | 55 | 56 | [ZERO_SENDER] 57 | address=tcp://127.0.0.1:5558 58 | hwm=200 59 | send_timeout=600 60 | recv_timeout=600 61 | socket_type=PUSH 62 | 63 | [ZERO_RECEIVER] 64 | address=tcp://127.0.0.1:5558 65 | hwm=200 66 | send_timeout=600 67 | recv_timeout=600 68 | socket_type=PULL 69 | -------------------------------------------------------------------------------- /win7-x64/native/KafkaGate64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/KafkaGate64.exe -------------------------------------------------------------------------------- /win7-x64/native/config.ini: -------------------------------------------------------------------------------- 1 | ################################################################ 2 | 3 | [sportfeedxml] 4 | broker=172.16.20.210:9092 5 | topic=sportfeedxml 6 | conf_section=sportfeedxml_conf 7 | topic_section=sportfeedxml_topic 8 | 9 | 10 | [sportfeedxml_conf] 11 | group.id=sportfeedxml_consumer 12 | socket.keepalive.enable=true 13 | 14 | queued.min.messages=1 15 | queued.max.messages.kbytes=1 16 | 17 | fetch.message.max.bytes=1048576 18 | fetch.min.bytes=1 19 | fetch.wait.max.ms=10 20 | fetch.error.backoff.ms=10 21 | 22 | [sportfeedxml_topic] 23 | offset.store.method=broker 24 | 25 | ################################################################ 26 | 27 | [consumer] 28 | #broker=10.16.14.71:9092 29 | topic=sportfeedxml_2 30 | conf_section=consumer_conf 31 | topic_section=consumer_topic 32 | 33 | 34 | [consumer_conf] 35 | group.id=sbofferdispatcher_live3 36 | socket.keepalive.enable=true 37 | socket.blocking.max.ms=100 38 | #socket.blocking.max.ms=1 39 | socket.nagle.disable=true 40 | 41 | enable.auto.commit=true 42 | auto.commit.interval.ms=100 43 | 44 | queued.min.messages=1 45 | #queued.min.messages=1 46 | queued.max.messages.kbytes=1 47 | 48 | fetch.wait.max.ms=0 49 | #fetch.message.max.bytes=1024 50 | #fetch.message.max.bytes=1000000000 51 | fetch.min.bytes=1 52 | fetch.wait.max.ms=1 53 | 54 | fetch.error.backoff.ms=1 55 | message.max.bytes=1000000000 56 | 57 | 58 | auto.offset.reset=latest 59 | #enable.partition.eof=false 60 | receive.message.max.bytes=1000000000 61 | 62 | api.version.request=false 63 | 64 | [consumer_topic] 65 | #offset.store.method=broker 66 | #offset.store.method=file 67 | offset.store.sync.interval.ms=-1 68 | 69 | 70 | ################################################################ 71 | 72 | 73 | #possible_topics=betslip;eventlotto;eventprematch;eventlive 74 | 75 | [producer] 76 | broker=172.16.20.210:9092 77 | topic=eventlotto 78 | conf_section=producer_conf 79 | topic_section=producer_topic 80 | 81 | 82 | [producer_conf] 83 | message.max.bytes=1500000 84 | socket.keepalive.enable=true 85 | socket.blocking.max.ms=1 86 | queue.buffering.max.messages=2 87 | queue.buffering.max.ms=0 88 | message.send.max.retries=10 89 | retry.backoff.ms=100 90 | compression.codec=none 91 | batch.num.messages=1 92 | delivery.report.only.error=true 93 | 94 | socket.nagle.disable=true 95 | 96 | 97 | [producer_topic] 98 | offset.store.method=broker 99 | -------------------------------------------------------------------------------- /win7-x64/native/libgcc_s_seh-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/libgcc_s_seh-1.dll -------------------------------------------------------------------------------- /win7-x64/native/librdkafka.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/librdkafka.dll -------------------------------------------------------------------------------- /win7-x64/native/librdkafkacpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/librdkafkacpp.dll -------------------------------------------------------------------------------- /win7-x64/native/libsodium-18.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/libsodium-18.dll -------------------------------------------------------------------------------- /win7-x64/native/libstdc++-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/libstdc++-6.dll -------------------------------------------------------------------------------- /win7-x64/native/libwinpthread-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/libwinpthread-1.dll -------------------------------------------------------------------------------- /win7-x64/native/libzmq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/libzmq.dll -------------------------------------------------------------------------------- /win7-x64/native/msvcr120.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/msvcr120.dll -------------------------------------------------------------------------------- /win7-x64/native/old/librdkafka.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/old/librdkafka.dll -------------------------------------------------------------------------------- /win7-x64/native/old/librdkafkacpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/old/librdkafkacpp.dll -------------------------------------------------------------------------------- /win7-x64/native/zlib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x64/native/zlib.dll -------------------------------------------------------------------------------- /win7-x86.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86.zip -------------------------------------------------------------------------------- /win7-x86/native/KafkaGate.ini: -------------------------------------------------------------------------------- 1 | [kafka_producer] 2 | broker=10.16.14.71:9092 3 | topic=sportfeedxml_2 4 | conf_section=kafka_producer_conf 5 | topic_section=kafka_producer_topic 6 | 7 | [kafka_producer_conf] 8 | message.max.bytes=1500000 9 | socket.keepalive.enable=true 10 | socket.blocking.max.ms=1 11 | queue.buffering.max.messages=2 12 | queue.buffering.max.ms=0 13 | message.send.max.retries=10 14 | retry.backoff.ms=100 15 | compression.codec=none 16 | batch.num.messages=1 17 | delivery.report.only.error=true 18 | socket.nagle.disable=true 19 | 20 | [kafka_producer_topic] 21 | offset.store.method=broker 22 | 23 | 24 | [kafka_consumer] 25 | broker=10.16.14.71:9092 26 | topic=sportfeedxml_2 27 | conf_section=kafka_consumer_conf 28 | topic_section=kafka_consumer_topic 29 | 30 | [kafka_consumer_conf] 31 | group.id=sbofferdispatcher_live17 32 | socket.keepalive.enable=true 33 | socket.blocking.max.ms=1 34 | #socket.blocking.max.ms=1 35 | socket.nagle.disable=true 36 | queued.min.messages=100000 37 | queued.max.messages.kbytes=1000000000 38 | fetch.wait.max.ms=0 39 | #fetch.message.max.bytes=1024 40 | #fetch.message.max.bytes=1000000000 41 | fetch.min.bytes=1 42 | fetch.wait.max.ms=1 43 | fetch.error.backoff.ms=1 44 | message.max.bytes=100000000 45 | auto.commit.interval.ms=5000 46 | enable.auto.offset.store=true 47 | auto.offset.reset=latest 48 | #enable.partition.eof=false 49 | receive.message.max.bytes=1000000000 50 | api.version.request=false 51 | 52 | [kafka_consumer_topic] 53 | offset.store.method=broker 54 | 55 | 56 | [ZERO_SENDER] 57 | address=tcp://127.0.0.1:5558 58 | hwm=200 59 | send_timeout=600 60 | recv_timeout=600 61 | socket_type=PUSH 62 | 63 | [ZERO_RECEIVER] 64 | address=tcp://127.0.0.1:5558 65 | hwm=200 66 | send_timeout=600 67 | recv_timeout=600 68 | socket_type=PULL 69 | -------------------------------------------------------------------------------- /win7-x86/native/KafkaGate32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/KafkaGate32.exe -------------------------------------------------------------------------------- /win7-x86/native/config.ini: -------------------------------------------------------------------------------- 1 | ################################################################ 2 | 3 | [sportfeedxml] 4 | broker=172.16.20.210:9092 5 | topic=sportfeedxml 6 | conf_section=sportfeedxml_conf 7 | topic_section=sportfeedxml_topic 8 | 9 | 10 | [sportfeedxml_conf] 11 | group.id=sportfeedxml_consumer 12 | socket.keepalive.enable=true 13 | 14 | queued.min.messages=1 15 | queued.max.messages.kbytes=1 16 | 17 | fetch.message.max.bytes=1048576 18 | fetch.min.bytes=1 19 | fetch.wait.max.ms=10 20 | fetch.error.backoff.ms=10 21 | 22 | [sportfeedxml_topic] 23 | offset.store.method=broker 24 | 25 | ################################################################ 26 | 27 | [consumer] 28 | #broker=10.16.14.71:9092 29 | topic=sportfeedxml_2 30 | conf_section=consumer_conf 31 | topic_section=consumer_topic 32 | 33 | 34 | [consumer_conf] 35 | group.id=sbofferdispatcher_live3 36 | socket.keepalive.enable=true 37 | socket.blocking.max.ms=100 38 | #socket.blocking.max.ms=1 39 | socket.nagle.disable=true 40 | 41 | enable.auto.commit=true 42 | auto.commit.interval.ms=100 43 | 44 | queued.min.messages=1 45 | #queued.min.messages=1 46 | queued.max.messages.kbytes=1 47 | 48 | fetch.wait.max.ms=0 49 | #fetch.message.max.bytes=1024 50 | #fetch.message.max.bytes=1000000000 51 | fetch.min.bytes=1 52 | fetch.wait.max.ms=1 53 | 54 | fetch.error.backoff.ms=1 55 | message.max.bytes=1000000000 56 | 57 | 58 | auto.offset.reset=latest 59 | #enable.partition.eof=false 60 | receive.message.max.bytes=1000000000 61 | 62 | api.version.request=false 63 | 64 | [consumer_topic] 65 | #offset.store.method=broker 66 | #offset.store.method=file 67 | offset.store.sync.interval.ms=-1 68 | 69 | 70 | ################################################################ 71 | 72 | 73 | #possible_topics=betslip;eventlotto;eventprematch;eventlive 74 | 75 | [producer] 76 | broker=172.16.20.210:9092 77 | topic=eventlotto 78 | conf_section=producer_conf 79 | topic_section=producer_topic 80 | 81 | 82 | [producer_conf] 83 | message.max.bytes=1500000 84 | socket.keepalive.enable=true 85 | socket.blocking.max.ms=1 86 | queue.buffering.max.messages=2 87 | queue.buffering.max.ms=0 88 | message.send.max.retries=10 89 | retry.backoff.ms=100 90 | compression.codec=none 91 | batch.num.messages=1 92 | delivery.report.only.error=true 93 | 94 | socket.nagle.disable=true 95 | 96 | 97 | [producer_topic] 98 | offset.store.method=broker 99 | -------------------------------------------------------------------------------- /win7-x86/native/libgcc_s_dw2-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/libgcc_s_dw2-1.dll -------------------------------------------------------------------------------- /win7-x86/native/librdkafka.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/librdkafka.dll -------------------------------------------------------------------------------- /win7-x86/native/librdkafkacpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/librdkafkacpp.dll -------------------------------------------------------------------------------- /win7-x86/native/libsodium-18.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/libsodium-18.dll -------------------------------------------------------------------------------- /win7-x86/native/libstdc++-6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/libstdc++-6.dll -------------------------------------------------------------------------------- /win7-x86/native/libwinpthread-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/libwinpthread-1.dll -------------------------------------------------------------------------------- /win7-x86/native/libzmq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/libzmq.dll -------------------------------------------------------------------------------- /win7-x86/native/msvcr120.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/msvcr120.dll -------------------------------------------------------------------------------- /win7-x86/native/old/librdkafka.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/old/librdkafka.dll -------------------------------------------------------------------------------- /win7-x86/native/old/librdkafkacpp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/old/librdkafkacpp.dll -------------------------------------------------------------------------------- /win7-x86/native/zlib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/win7-x86/native/zlib.dll -------------------------------------------------------------------------------- /zero2kafka.pas: -------------------------------------------------------------------------------- 1 | unit Zero2Kafka; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | interface 6 | 7 | uses 8 | Classes, SysUtils, Crt, 9 | Kafka, KafkaClass, zmq, ZMQClass; 10 | 11 | type 12 | 13 | { TMyKafkaConsumer } 14 | 15 | TMyKafkaConsumer = class 16 | constructor Create(); 17 | procedure OnKafkaMessageReceived(InMessage: String; InKey: String; OutMsg: Prd_kafka_message_t); 18 | procedure OnKafkaMessageEOF(InMessage: String); 19 | procedure OnKafkaMessageErr(InError: String); 20 | procedure OnKafkaTick(InWhat: String); 21 | end; 22 | 23 | procedure StartZeroMQProducer_21(InIniFileName: String); 24 | procedure StartZeroMQConsumer_22(InIniFileName: String); 25 | procedure StartKafkaConsumer_23(InIniFileName: String); 26 | 27 | implementation 28 | 29 | procedure WriteStatus(InString: String); 30 | begin 31 | Writeln(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now) + ' ' + InString); 32 | end; 33 | 34 | // callback for Kafka send message 35 | procedure Zero2Kafka_dr_msg_cb (rk: Prd_kafka_t; rkmessage: Prd_kafka_message_t; opaque: Pointer); cdecl; 36 | begin 37 | if (rkmessage^.err <> 0) then begin 38 | WriteStatus(Format('Message delivery failed: %s', [rd_kafka_err2str(rkmessage^.err)])); 39 | end 40 | else begin 41 | WriteStatus(Format('Message delivered (bytes: %d, partition: %d)', [rkmessage^.len, rkmessage^.partion])); 42 | end; 43 | end; 44 | 45 | 46 | { TMyKafkaConsumer } 47 | 48 | constructor TMyKafkaConsumer.Create(); 49 | begin 50 | inherited Create(); 51 | end; 52 | 53 | procedure TMyKafkaConsumer.OnKafkaMessageReceived(InMessage: String; 54 | InKey: String; OutMsg: Prd_kafka_message_t); 55 | begin 56 | WriteStatus('ReceiveMessage: ' + InMessage); 57 | end; 58 | 59 | procedure TMyKafkaConsumer.OnKafkaMessageEOF(InMessage: String); 60 | begin 61 | WriteStatus('ReceiveKafkaEOF'); 62 | end; 63 | 64 | procedure TMyKafkaConsumer.OnKafkaMessageErr(InError: String); 65 | begin 66 | WriteStatus('ReceiveKafkaERR: ' + InError); 67 | end; 68 | 69 | procedure TMyKafkaConsumer.OnKafkaTick(InWhat: String); 70 | begin 71 | // WriteStatus('ReceiveKafkaTick: ' + InWhat); 72 | end; 73 | 74 | 75 | procedure StartZeroMQProducer_21(InIniFileName: String); 76 | var My0MQContext: T0MQContext; 77 | My0MQSocket: T0MQSocket; 78 | My0MQSetup: T0MQSetup; 79 | MyString: String; 80 | MyError: Integer; 81 | begin 82 | My0MQSocket := nil; 83 | 84 | try 85 | // read kafka and 0mq configuration 86 | ZeroMQReadConfiguration(InIniFileName, 'ZERO_SENDER', My0MQSetup); 87 | 88 | // create 0mq pusher socket 89 | My0MQContext := T0MQContext.Create(); 90 | My0MQSocket := T0MQSocket.Create(My0MQContext._Context); 91 | 92 | // setup and connect 0mqsocket 93 | // we can support PUBLISH-SUBSCRIBE pattern or PUSH-PULL pattern 94 | if My0MQSetup.socket_type = 'PUB' then begin 95 | My0MQSocket.GetSocket(ZMQ_PUB); 96 | end 97 | else begin 98 | My0MQSocket.GetSocket(ZMQ_PUSH); 99 | end; 100 | My0MQSocket.SetSockOptInteger(ZMQ_SNDHWM, My0MQSetup.hwm); 101 | My0MQSocket.SetSockOptInteger(ZMQ_SNDTIMEO, My0MQSetup.send_timeout); 102 | My0MQSocket.ConnectSocket(My0MQSetup.address); 103 | 104 | while true do begin 105 | if KeyPressed then begin // <--- CRT function to test key press 106 | if ReadKey = ^C then begin // read the key pressed 107 | WriteStatus('Ctrl-C pressed'); 108 | Break; 109 | end; 110 | end; 111 | 112 | MyString := Format('<xml date="%s"/>', [FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now)]); 113 | try 114 | MyError := My0MQSocket.Send(MyString); 115 | if MyString <> '' then begin 116 | WriteStatus('SendMessage: ' + MyString); 117 | end; 118 | Sleep(100); 119 | except 120 | on E: Exception do begin 121 | WriteStatus('Error: ' + E.Message); 122 | end; 123 | end; 124 | end; 125 | 126 | if My0MQSocket <> nil then FreeAndNil(My0MQSocket); 127 | if My0MQContext <> nil then FreeAndNil(My0MQContext); 128 | except 129 | on E: Exception do begin 130 | WriteStatus('Error: ' + E.Message); 131 | WriteStatus('ZeroMQDumpSetup: ' + ZeroMQDumpSetup(My0MQSetup)); 132 | if My0MQSocket <> nil then FreeAndNil(My0MQSocket); 133 | if My0MQContext <> nil then FreeAndNil(My0MQContext); 134 | end; 135 | end; 136 | end; 137 | 138 | procedure StartZeroMQConsumer_22(InIniFileName: String); 139 | var MyProducer: TKafkaProducer; 140 | MyKafkaSetup: TKafkaSetup; 141 | 142 | My0MQContext: T0MQContext; 143 | My0MQSocket: T0MQSocket; 144 | My0MQSetup: T0MQSetup; 145 | 146 | MyError: Integer; 147 | MyString: String; 148 | MyKey: String; 149 | F: Integer; 150 | My_dr_msg_cb: TProc_dr_msg_cb; // Callback for Kafka Producer 151 | begin 152 | MyProducer := nil; 153 | My0MQSocket := nil; 154 | 155 | try 156 | // read kafka and 0mq configuration 157 | KafkaReadConfiguration(InIniFileName, 'kafka_producer', MyKafkaSetup); 158 | ZeroMQReadConfiguration(InIniFileName, 'ZERO_RECEIVER', My0MQSetup); 159 | 160 | // create kafka producer 161 | MyProducer := TKafkaProducer.Create(True); 162 | 163 | // create 0mq pusher socket 164 | My0MQContext := T0MQContext.Create(); 165 | My0MQSocket := T0MQSocket.Create(My0MQContext._Context); 166 | 167 | // setup and connect 0mqsocket 168 | // we can support PUBLISH-SUBSCRIBE pattern or PUSH-PULL pattern 169 | if My0MQSetup.socket_type = 'SUB' then begin 170 | My0MQSocket.GetSocket(ZMQ_SUB); 171 | end 172 | else begin 173 | My0MQSocket.GetSocket(ZMQ_PULL); 174 | end; 175 | My0MQSocket.SetSockOptInteger(ZMQ_SNDHWM, My0MQSetup.hwm); 176 | My0MQSocket.SetSockOptInteger(ZMQ_SNDTIMEO, My0MQSetup.send_timeout); 177 | My0MQSocket.BindSocket(My0MQSetup.address); 178 | 179 | // Start producer 180 | My_dr_msg_cb := @Zero2Kafka_dr_msg_cb; 181 | MyProducer.StartProducer(MyKafkaSetup, My_dr_msg_cb); 182 | 183 | F := 0; 184 | // start reading messages from ZeroMQ socket 185 | while true do begin 186 | if KeyPressed then begin // <--- CRT function to test key press 187 | if ReadKey = ^C then begin // read the key pressed 188 | WriteStatus('Ctrl-C pressed'); 189 | Break; 190 | end; 191 | end; 192 | 193 | MyString := ''; 194 | try 195 | MyError := My0MQSocket.Recv(MyString, ZMQ_DONTWAIT, 100); 196 | if MyString <> '' then begin 197 | F := F +1; 198 | WriteStatus('ReceivedMessage: ' + MyString); 199 | WriteStatus('Send message to kafka'); 200 | 201 | MyKey := IntToStr(F mod 100); // Fake Key 202 | MyProducer.ProduceMessage(MyKey, MyString); 203 | 204 | WriteStatus('Message Sent to Kafka Topic'); 205 | end; 206 | except 207 | on E: Exception do begin 208 | WriteStatus('Error: ' + E.Message); 209 | end; 210 | end; 211 | end; 212 | 213 | if My0MQSocket <> nil then FreeAndNil(My0MQSocket); 214 | if My0MQContext <> nil then FreeAndNil(My0MQContext); 215 | if MyProducer <> nil then FreeAndNil(MyProducer); 216 | except 217 | on E: Exception do begin 218 | WriteStatus('Error: ' + E.Message); 219 | WriteStatus('ZeroMQDumpSetup: ' + ZeroMQDumpSetup(My0MQSetup)); 220 | if My0MQSocket <> nil then FreeAndNil(My0MQSocket); 221 | if My0MQContext <> nil then FreeAndNil(My0MQContext); 222 | if MyProducer <> nil then FreeAndNil(MyProducer); 223 | end; 224 | end; 225 | end; 226 | 227 | procedure StartKafkaConsumer_23(InIniFileName: String); 228 | var MyConsumer: TKafkaConsumer; 229 | MyKafkaSetup: TKafkaSetup; 230 | 231 | MySpecificKafkaConsumer: TMyKafkaConsumer; 232 | MyMaxReadBytes: Integer; 233 | begin 234 | MyMaxReadBytes := 128; // I want only 128 bytes messages - rest is trimmed 235 | MyConsumer := nil; 236 | MySpecificKafkaConsumer := nil; 237 | 238 | try 239 | // read kafka and 0mq configuration 240 | KafkaReadConfiguration(InIniFileName, 'kafka_consumer', MyKafkaSetup); 241 | 242 | // create kafka consumer 243 | MyConsumer := TKafkaConsumer.Create(True); 244 | 245 | // create callback object in which I will receive kafka messages and 246 | // send it to 0mq socket 247 | MySpecificKafkaConsumer := TMyKafkaConsumer.Create; 248 | 249 | // start kafka consumer 250 | MyConsumer.StartConsumer(MyKafkaSetup, 251 | @MySpecificKafkaConsumer.OnKafkaMessageReceived, 252 | @MySpecificKafkaConsumer.OnKafkaMessageEOF, 253 | @MySpecificKafkaConsumer.OnKafkaMessageErr, 254 | @MySpecificKafkaConsumer.OnKafkaTick, 255 | MyMaxReadBytes); // for test receive only 128 bytes 256 | 257 | if MySpecificKafkaConsumer <> nil then FreeAndNil(MySpecificKafkaConsumer); 258 | if MyConsumer <> nil then FreeAndNil(MyConsumer); 259 | except 260 | on E: Exception do begin 261 | WriteStatus('Error: ' + E.Message); 262 | if MySpecificKafkaConsumer <> nil then FreeAndNil(MySpecificKafkaConsumer); 263 | if MyConsumer <> nil then FreeAndNil(MyConsumer); 264 | end; 265 | end; 266 | end; 267 | 268 | 269 | end. 270 | 271 | -------------------------------------------------------------------------------- /zlib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dinmil/KafkaGate/4e4a50a691a8fcdcbe4524dc99a7ef798ab88fa0/zlib.dll -------------------------------------------------------------------------------- /zmqclass.pas: -------------------------------------------------------------------------------- 1 | unit ZMQClass; 2 | 3 | {$mode objfpc}{$H+} 4 | 5 | interface 6 | 7 | uses 8 | Classes, SysUtils, 9 | IniFiles, 10 | 11 | zmq, ctypes; 12 | 13 | type 14 | T0MQSetup = record 15 | address: string; // example is tcp://172.17.41.208:5558 16 | hwm: integer; // high water mark 17 | send_timeout: integer; // send timeout 18 | recv_timeout: integer; // receiving timeout 19 | socket_type: string; // PUB, SUB, PUSH, PULL ... 20 | end; 21 | 22 | 23 | { E0MQError } 24 | // Error nadling 25 | // Methods that create objects return NULL if they fail. 26 | // Methods that process data may return the number of bytes processed, or -1 on an error or failure. 27 | // Other methods return 0 on success and -1 on an error or failure. 28 | // The error code is provided in errno or zmq_errno(). 29 | // A descriptive error text for logging is provided by zmq_strerror(). 30 | 31 | 32 | E0MQError = class(Exception) 33 | public 34 | _ErrNo: Integer; 35 | _ErrMsg: String; 36 | constructor Create(InErrNo: Integer; InErrMsg: String); 37 | destructor Destroy; override; 38 | end; 39 | 40 | { T0MQContext } 41 | 42 | T0MQContext = class 43 | _Context: Pointer; 44 | public 45 | constructor Create; 46 | destructor Destroy; override; 47 | function GetContext: Pointer; 48 | end; 49 | 50 | { T0MQSocket } 51 | 52 | T0MQSocket = class 53 | _Context: Pointer; 54 | _Socket: Pointer; 55 | _SocketType: cint; 56 | _BindString: String; 57 | _ConnectString: String; 58 | _RecvBuffer: array[0..(65536 * 100)-1] of char; 59 | public 60 | constructor Create(InContext: Pointer); overload; 61 | constructor Create(InContext: T0MQContext); overload; 62 | destructor Destroy; override; 63 | 64 | procedure CleanUp; 65 | function GetSocket(InSocketType: cint): Pointer; 66 | function BindSocket(InBindString: String): cint; 67 | function ConnectSocket(InConnectString: String): cint; 68 | function CloseSocket: cint; 69 | 70 | function Send(InBuffer: Pointer; InLen: csize_t; InFlags: cint = 0): cint; overload; 71 | function Send(var InString: String): cint; 72 | function Recv(InBuffer: Pointer; InBufferSize: cint; InFlags: cint = 0): cint; overload; 73 | function Recv(var OutString: String; InFlags: cint = 0; InHowMuchMilliseconds: cint = 0): cint; overload; 74 | 75 | function SetSockOptInteger(InOption: cint; InValue: Integer): cint; 76 | function SetSockOptInt64(InOption: cint; InValue: Int64): cint; 77 | 78 | function GetSockOptInteger(InOption: cint): Integer; 79 | function GetSockOptInt64(InOption: cint): Int64; 80 | end; 81 | 82 | var InitT0MQSetup: T0MQSetup = ({%H-}); 83 | 84 | function Get0MQError(InErrorCode: cint): String; 85 | procedure Raise0MQError(InErrNo: Integer; 86 | InErrMsg: String); 87 | procedure ZeroMQReadConfiguration(InIniFile: TIniFile; InSection: String; var Out0MQSetup: T0MQSetup); overload; 88 | procedure ZeroMQReadConfiguration(InIniFileName: String; InSection: String; var Out0MQSetup: T0MQSetup); overload; 89 | function ZeroMQDumpSetup(var In0MQSetup: T0MQSetup): String; 90 | 91 | implementation 92 | 93 | function Get0MQError(InErrorCode: cint): String; 94 | var MyErrPChar: PChar; 95 | MyResult: String; 96 | begin 97 | MyResult:= ''; 98 | MyErrPChar := zmq_strerror(InErrorCode); 99 | MyResult := String(MyErrPChar); 100 | Result := MyResult; 101 | end; 102 | 103 | procedure Raise0MQError(InErrNo: Integer; InErrMsg: String); 104 | begin 105 | raise E0MQError.Create(InErrNo, InErrMsg); 106 | end; 107 | 108 | { T0MQContext } 109 | 110 | constructor T0MQContext.Create; 111 | var MyError: cint; 112 | MyErrorString: String; 113 | begin 114 | _Context := nil; 115 | _Context := zmq.zmq_ctx_new(); 116 | if _Context = nil then begin 117 | MyError := zmq_errno(); 118 | MyErrorString := Get0MQError(MyError); 119 | Raise0MQError(MyError, MyErrorString); 120 | end; 121 | end; 122 | 123 | destructor T0MQContext.Destroy; 124 | var MyRC: cint; 125 | MyError: cint; 126 | MyErrorString: String; 127 | begin 128 | MyRC := zmq_ctx_destroy (_Context); 129 | if MyRC = -1 then begin 130 | MyError := zmq_errno(); 131 | MyErrorString := Get0MQError(MyError); 132 | Raise0MQError(MyError, MyErrorString); 133 | end; 134 | 135 | inherited Destroy; 136 | end; 137 | 138 | function T0MQContext.GetContext: Pointer; 139 | begin 140 | Result := _Context; 141 | end; 142 | 143 | { E0MQError } 144 | 145 | constructor E0MQError.Create(InErrNo: Integer; InErrMsg: String); 146 | begin 147 | inherited Create(InErrMsg); 148 | _ErrNo := InErrNo; 149 | _ErrMsg := InErrMsg; 150 | end; 151 | 152 | destructor E0MQError.Destroy; 153 | begin 154 | inherited Destroy; 155 | end; 156 | 157 | { T0MQSocket } 158 | 159 | constructor T0MQSocket.Create(InContext: Pointer); 160 | begin 161 | CleanUp; 162 | _Context := InContext; 163 | end; 164 | 165 | constructor T0MQSocket.Create(InContext: T0MQContext); 166 | begin 167 | _Context := InContext.GetContext; 168 | end; 169 | 170 | destructor T0MQSocket.Destroy; 171 | begin 172 | try 173 | if _Socket <> nil then begin 174 | CloseSocket; 175 | end; 176 | except 177 | // I dont care about error 178 | end; 179 | 180 | CleanUp; 181 | inherited Destroy; 182 | end; 183 | 184 | procedure T0MQSocket.CleanUp; 185 | begin 186 | _Context := nil; 187 | _Socket := nil; 188 | _SocketType := 0; 189 | _BindString := ''; 190 | _ConnectString := ''; 191 | end; 192 | 193 | function T0MQSocket.GetSocket(InSocketType: cint): Pointer; 194 | var MyResult: Pointer; 195 | MyError: cint; 196 | MyErrorString: String; 197 | begin 198 | MyResult := nil; 199 | _SocketType := InSocketType; 200 | MyResult := zmq_socket (_Context, InSocketType); 201 | if MyResult = nil then begin 202 | MyError := zmq_errno(); 203 | MyErrorString := Get0MQError(MyError); 204 | Raise0MQError(MyError, MyErrorString); 205 | end; 206 | _Socket := MyResult; 207 | Result := MyResult; 208 | end; 209 | 210 | function T0MQSocket.BindSocket(InBindString: String): cint; 211 | var MyRC: cint; 212 | MyError: cint; 213 | MyErrorString: String; 214 | begin 215 | _BindString := InBindString; 216 | MyRC := zmq_bind(_Socket, PChar(InBindString)); 217 | if MyRC = -1 then begin 218 | MyError := zmq_errno(); 219 | MyErrorString := Get0MQError(MyError); 220 | Raise0MQError(MyError, MyErrorString); 221 | end; 222 | Result := MyRC; 223 | end; 224 | 225 | function T0MQSocket.ConnectSocket(InConnectString: String): cint; 226 | var MyRC: cint; 227 | MyError: cint; 228 | MyErrorString: String; 229 | begin 230 | _ConnectString := InConnectString; 231 | MyRC := zmq_connect(_Socket, PChar(InConnectString)); 232 | if MyRC = -1 then begin 233 | MyError := zmq_errno(); 234 | MyErrorString := Get0MQError(MyError); 235 | Raise0MQError(MyError, MyErrorString); 236 | end; 237 | Result := MyRC; 238 | end; 239 | 240 | function T0MQSocket.CloseSocket: cint; 241 | var MyRC: cint; 242 | MyError: cint; 243 | MyErrorString: String; 244 | begin 245 | MyRC := zmq_close(_Socket); 246 | if MyRC = -1 then begin 247 | MyError := zmq_errno(); 248 | MyErrorString := Get0MQError(MyError); 249 | Raise0MQError(MyError, MyErrorString); 250 | end; 251 | CleanUp; 252 | Result := MyRC; 253 | end; 254 | 255 | function T0MQSocket.Send(InBuffer: Pointer; InLen: csize_t; InFlags: cint): cint; 256 | var MyRC: cint; 257 | MyError: cint; 258 | MyErrorString: String; 259 | begin 260 | MyRC := zmq_send(_Socket, InBuffer, InLen, InFlags); 261 | if MyRC = -1 then begin 262 | MyError := zmq_errno(); 263 | MyErrorString := Get0MQError(MyError); 264 | Raise0MQError(MyError, MyErrorString); 265 | end; 266 | Result := MyRC; 267 | end; 268 | 269 | function T0MQSocket.Send(var InString: String): cint; 270 | begin 271 | Result := Send(Pchar(InString), Length(InString), 0); 272 | end; 273 | 274 | function T0MQSocket.Recv(InBuffer: Pointer; InBufferSize: cint; InFlags: cint): cint; 275 | var MyRC: cint; 276 | MyError: cint; 277 | MyErrorString: String; 278 | begin 279 | MyRC := zmq_recv(_Socket, InBuffer, InBufferSize, InFlags); 280 | if ((MyRC = -1) and (InFlags = 0)) then begin 281 | MyError := zmq_errno(); 282 | MyErrorString := Get0MQError(MyError); 283 | Raise0MQError(MyError, MyErrorString); 284 | end; 285 | Result := MyRC; 286 | end; 287 | 288 | function T0MQSocket.Recv(var OutString: String; InFlags: cint; 289 | InHowMuchMilliseconds: cint): cint; 290 | var MyResult: cint; 291 | begin 292 | FillChar(_RecvBuffer, SizeOf(_RecvBuffer), 0); 293 | if InFlags = ZMQ_DONTWAIT then begin 294 | while InHowMuchMilliseconds > 0 do begin 295 | MyResult := Recv(@_RecvBuffer, SizeOf(_RecvBuffer), InFlags); 296 | if MyResult = -1 then begin 297 | if zmq_errno = ZMQ_EAGAIN then begin 298 | InHowMuchMilliseconds := InHowMuchMilliseconds - 100; 299 | Sleep(100); 300 | end 301 | else begin 302 | break; 303 | end; 304 | end 305 | else begin 306 | Break; 307 | end; 308 | end; 309 | end 310 | else begin 311 | MyResult := Recv(@_RecvBuffer, SizeOf(_RecvBuffer), InFlags); 312 | end; 313 | OutString := _RecvBuffer; 314 | Result := MyResult; 315 | end; 316 | 317 | function T0MQSocket.SetSockOptInteger(InOption: cint; InValue: Integer): cint; 318 | var MyRC: cint; 319 | MyError: cint; 320 | MyErrorString: String; 321 | begin 322 | MyRC := zmq_setsockopt(_Socket, InOption, @InValue, sizeof(InValue)); 323 | if MyRC = -1 then begin 324 | MyError := zmq_errno(); 325 | MyErrorString := Get0MQError(MyError); 326 | Raise0MQError(MyError, MyErrorString); 327 | end; 328 | Result := MyRC; 329 | end; 330 | 331 | function T0MQSocket.SetSockOptInt64(InOption: cint; InValue: Int64): cint; 332 | var MyRC: cint; 333 | MyError: cint; 334 | MyErrorString: String; 335 | begin 336 | MyRC := zmq_setsockopt(_Socket, InOption, @InValue, sizeof(InValue)); 337 | if MyRC = -1 then begin 338 | MyError := zmq_errno(); 339 | MyErrorString := Get0MQError(MyError); 340 | Raise0MQError(MyError, MyErrorString); 341 | end; 342 | Result := MyRC; 343 | end; 344 | 345 | function T0MQSocket.GetSockOptInteger(InOption: cint): Integer; 346 | var MyRC: cint; 347 | MyError: cint; 348 | MyErrorString: String; 349 | MyValue: Integer; 350 | MySize: csize_t; //size_t 351 | begin 352 | MyValue := 0; 353 | MySize := SizeOf(MyValue); 354 | MyRC := zmq_getsockopt(_Socket, InOption, @MyValue, @MySize); 355 | if MyRC = -1 then begin 356 | MyError := zmq_errno(); 357 | MyErrorString := Get0MQError(MyError); 358 | Raise0MQError(MyError, MyErrorString); 359 | end; 360 | Result := MyValue; 361 | end; 362 | 363 | function T0MQSocket.GetSockOptInt64(InOption: cint): Int64; 364 | var MyRC: cint; 365 | MyError: cint; 366 | MyErrorString: String; 367 | MyValue: Int64; 368 | MySize: csize_t; //size_t 369 | begin 370 | MyValue := 0; 371 | MySize := SizeOf(MyValue); 372 | MyRC := zmq_getsockopt(_Socket, InOption, @MyValue, @MySize); 373 | if MyRC = -1 then begin 374 | MyError := zmq_errno(); 375 | MyErrorString := Get0MQError(MyError); 376 | Raise0MQError(MyError, MyErrorString); 377 | end; 378 | Result := MyValue; 379 | end; 380 | 381 | procedure ZeroMQReadConfiguration(InIniFile: TIniFile; InSection: String; 382 | var Out0MQSetup: T0MQSetup); 383 | begin 384 | Out0MQSetup := InitT0MQSetup; 385 | Out0MQSetup.address := InIniFile.ReadString(InSection, 'address', ''); 386 | Out0MQSetup.hwm := InIniFile.ReadInteger(InSection, 'hwm', 200); 387 | Out0MQSetup.send_timeout := InIniFile.ReadInteger(InSection, 'send_timeout', 0); 388 | Out0MQSetup.recv_timeout := InIniFile.ReadInteger(InSection, 'recv_timeout', 0); 389 | Out0MQSetup.socket_type := InIniFile.ReadString(InSection, 'socket_type', 'PULL'); 390 | end; 391 | 392 | procedure ZeroMQReadConfiguration(InIniFileName: String; InSection: String; 393 | var Out0MQSetup: T0MQSetup); 394 | var MyIniFile: TIniFile; 395 | begin 396 | Out0MQSetup := InitT0MQSetup; 397 | MyIniFile := nil; 398 | try 399 | if FileExists(InIniFileName) then begin 400 | MyIniFile := TIniFile.Create(InIniFileName); 401 | ZeroMQReadConfiguration(MyIniFile, InSection, Out0MQSetup); 402 | if MyIniFile <> nil then begin 403 | FreeAndNil(MyIniFile); 404 | end; 405 | end; 406 | except 407 | if MyIniFile <> nil then begin 408 | FreeAndNil(MyIniFile); 409 | end; 410 | end; 411 | end; 412 | 413 | function ZeroMQDumpSetup(var In0MQSetup: T0MQSetup): String; 414 | begin 415 | Result := Format('address=%s' + #13#10 + 416 | 'hwm=%d' + #13#10 + 417 | 'recv_timeout=%d' + #13#10 + 418 | 'end_timeout=%d' + #13#10 + 419 | 'socket_type=%s', 420 | [ 421 | In0MQSetup.address, 422 | In0MQSetup.hwm, 423 | In0MQSetup.recv_timeout, 424 | In0MQSetup.send_timeout, 425 | In0MQSetup.socket_type 426 | ]); 427 | end; 428 | 429 | 430 | end. 431 | 432 | --------------------------------------------------------------------------------