├── 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 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/KafkaGate.ctps:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
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 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/KafkaGate.lps:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
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 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
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 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
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 := '' + FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now) + '';
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 |
2 |
3 |
4 |
5 |
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 |
2 |
3 |
4 |
5 |
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 |
10 | New in this version from 2018-02-27
11 |
12 | New librdkafka 11.3
13 |
14 | Compatibility with Linux 32 and Linux 64
15 |
16 | New Way to sebd message in Kafka Pas Application
17 |
18 | Compiled with new Code Typhon 6.40
19 |
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 |
29 |
30 |
31 |
32 |
33 |
34 | KafkaGate Console Menu
35 |
36 |
writeln('Menu');
37 |
writeln('1. Start consumer - C Style');
38 |
writeln('2. Start producer - C Style');
39 |
writeln('3. Start consumer - Pas Style');
40 |
writeln('4. Start producer - Pas Style');
41 |
writeln('KAFKA 2 ZEROMQ');
42 |
writeln('config_file: KafkaGate.ini');
43 |
writeln('Purpose of this pipeline is');
44 |
writeln('- put message to kafka->consume message from kafka->send message to 0mq->receive message from 0mq');
45 |
writeln('11. Start Kafka Producer');
46 |
writeln('12. Start Kafka Consumer -> Start ZEROMQ PUSH');
47 |
writeln('13. Start ZEROMQ PULL');
48 |
writeln('ZEROMQ 2 KAFKA');
49 |
writeln('config_file: KafkaGate.ini');
50 |
writeln('Purpose of this pipeline is');
51 |
writeln('- put message to 0mq->consume message from 0mq->send message to kafka->receive message from kafka');
52 |
writeln('21. Start ZERMOQ Producer PUSH');
53 |
writeln('22. Start ZEROMQ PULL -> Kafka Producer');
54 |
writeln('23. Start Kafka Consumer');
55 |
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 -p "
23 | @echo ""
24 | @echo "# or consumer"
25 | @echo "./$@ -C -t -p "
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 "./$@ .."
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 -p -s "
53 | @echo ""
54 | @echo "# or consumer"
55 | @echo "./$@ -C -t -p "
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 -p "
82 | @echo ""
83 | @echo "# or consumer"
84 | @echo "./$@ -C -t -p "
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
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 |
42 | #ifndef _MSC_VER
43 | #include
44 | #endif
45 |
46 | #ifdef _MSC_VER
47 | #include "../win32/wingetopt.h"
48 | #include
49 | #elif _AIX
50 | #include
51 | #else
52 | #include
53 | #include
54 | #endif
55 |
56 | /*
57 | * Typically include path in a real application would be
58 | * #include
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&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 &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(message->len()),
187 | static_cast(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 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 [options] topic1 topic2..\n"
338 | "\n"
339 | "librdkafka version %s (0x%08x)\n"
340 | "\n"
341 | " Options:\n"
342 | " -g Consumer group id\n"
343 | " -b Broker address (localhost:9092)\n"
344 | " -z 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 Enable statistics\n"
351 | " -X 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 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 *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::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
36 | #include
37 | #include
38 |
39 |
40 | /* Typical include path would be , 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 \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('', [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 |
--------------------------------------------------------------------------------