From bf7bf74b02dc5849a1b8b5042a76e2073a3cdd05 Mon Sep 17 00:00:00 2001 From: Dan Garner Date: Fri, 13 Jan 2017 13:45:20 +0000 Subject: [PATCH 1/8] Add support for IPv6 via config option xibosignage/xibo#1009 --- bin/xmr.phar | Bin 400843 -> 430131 bytes composer.lock | 41 +++++++++++++++++++++++++---------------- config.json | 4 +++- index.php | 14 ++++++++++++-- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/bin/xmr.phar b/bin/xmr.phar index 795e5b1474f5427f8d870b38c9d3dc706da87fb1..eda2eecfadbd3cef78336e189b3d17075b5582bd 100755 GIT binary patch delta 26358 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 P=Ii*d`=B{9=gs_ojpIUo delta 10821 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.90 <3.0", + "sentry/sentry": "^0.13", "swiftmailer/swiftmailer": "~5.3" }, "suggest": { @@ -96,9 +96,9 @@ "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", "php-console/php-console": "Allow sending log messages to Google Chrome", - "raven/raven": "Allow sending log messages to a Sentry server", "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "sentry/sentry": "Allow sending log messages to a Sentry server" }, "type": "library", "extra": { @@ -129,26 +129,34 @@ "logging", "psr-3" ], - "time": "2016-04-12 18:29:35" + "time": "2016-11-26 00:15:39" }, { "name": "psr/log", - "version": "1.0.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "shasum": "" }, + "require": { + "php": ">=5.3.0" + }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, "autoload": { - "psr-0": { - "Psr\\Log\\": "" + "psr-4": { + "Psr\\Log\\": "Psr/Log/" } }, "notification-url": "https://packagist.org/downloads/", @@ -162,12 +170,13 @@ } ], "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], - "time": "2012-12-21 11:40:51" + "time": "2016-10-10 12:19:37" }, { "name": "react/event-loop", diff --git a/config.json b/config.json index deca50a..15b144b 100644 --- a/config.json +++ b/config.json @@ -1,5 +1,7 @@ { "listenOn": "tcp://localhost:50001", "pubOn": ["tcp://localhost:9505", "tcp://localhost:50002"], - "debug": true + "debug": true, + "ipv6RespSupport": false, + "ipv6PubSupport": false } diff --git a/index.php b/index.php index d78d83f..fc1fb62 100644 --- a/index.php +++ b/index.php @@ -2,8 +2,8 @@ > CMS: Register @@ -56,9 +56,19 @@ function exception_error_handler($severity, $message, $file, $line) { $responder = $context->getSocket(ZMQ::SOCKET_REP); $responder->bind($config->listenOn); + // Set RESP socket options + if (isset($config->ipv6RespSupport) && $config->ipv6RespSupport === true) { + $responder->setSockOpt(\ZMQ::SOCKOPT_IPV6, true); + } + // Pub socket for messages to Players (subs) $publisher = $context->getSocket(ZMQ::SOCKET_PUB); + // Set PUB socket options + if (isset($config->ipv6PubSupport) && $config->ipv6PubSupport === true) { + $publisher->setSockOpt(\ZMQ::SOCKOPT_IPV6, true); + } + foreach ($config->pubOn as $pubOn) { $log->info(sprintf('Bind to %s for Publish.', $pubOn)); $publisher->bind($pubOn); From 1e232f64f847733201dfd806e245348e8580b175 Mon Sep 17 00:00:00 2001 From: Dan Garner Date: Fri, 13 Jan 2017 15:10:33 +0000 Subject: [PATCH 2/8] Add support for IPv6 via config option - +logging and default config xibosignage/xibo#1009 --- bin/xmr.phar | Bin 430131 -> 477638 bytes config.json | 6 +++--- index.php | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/bin/xmr.phar b/bin/xmr.phar index eda2eecfadbd3cef78336e189b3d17075b5582bd..6d5c40949369c5b8dbaa14d6107d5671ffc21f61 100755 GIT binary patch delta 31705 zcmeHwd3YSfwXeFTTgzx0?Yq?4JR@71ZM?~gB-@fL+p=Xz-eu&GrY%i8ni*!X5g2U9 zB?Jt3DR3p+;N`|Qxw&y}?3j4K0b>IJ=K;aokPvdg3p|_6Yr+yR#P3vfPtQox(=)v9 ze((PC^d(eJcb!w`RGq3ib)ivD9mv3K*7Bfqe$VDp? z6Z6S)_dbTwN;1%KX1etB8)m6tW_(NxsX@vG`k6=2t?UBn=|Q%e(zd0=#6123dm-A9 zSBL6T;?W#kwp3%SZn-)!(G6WDC7l`<6C-|@w*;D%NISUS$Z&y^Y~=9ftqn|Mi|AM!CV7iMg}iGEa6 zhnyJ+V{GRB4J*XHL5E|*e6!tR6J52=LFeXVsVP!UW4_rh%aMSRVr3P^#4a&hlvN<* zm(MTxKBzDSJrkQn1+oFD z=3|5wm&@S_lHp*nRGXCl>76kHY&oe+?f;#NiAmeA={k%^9eOTLk5cnu z(Kk71^kEu^U-QBFyU?1PX{al=nBM$VQcR5D%CU5qVw7S`yXflox~yhfhs)6~y4?=C zD2Vbfk@D4TMdxYrM|0)of1fK)-nu+_P`>ZKIG<;x?PTj>VtmgWZ1T5*?$6Js4`#73 zF_){Bk3-EFb*QOCk1poR3m99l$}k1iQPTCK{QWXmoPSg_4IL=Rlhi(0Altc6xYBT} zLaIv2H_qI4i1qXjBT^21cIG72khFWCMAGmE^!xO6X0i}WLpmWX?`c^n zQd&>G{!L)yPYU^Ho=|A`Os+x7k55;)(P2{tdPOjx-9oy-00I)pNtyciJR5pSn4VV! zmPc-q^3->d4v*wHrc{tLUr^eRS0XR)r2OX>p8d>UwH%!kipmy=8$}zLyB#t|QaF_#WeLTOCQWRv4lU}Hjt%EV+h z5%^Vk$wKEU=1BF8l`_vwmGdd#Bd`vA`oxs`(f%=}6!##ZB5DzN5i@4KMAh!U_~Doa z>CRhY|BikRx^=8PU53XN z6rd^!`6%r-SsreW2B96XjL9p+V7# z=xr*aYL``23*jqoA-yE^0j*zFrP`XqrNM)+pq&I9NNZ4e*x?oW&33^pdi+Xw21OOt z`0mG;*fv>jx8QYyN`l*Fb`Of~YQbx_h%Ptm<)T{v|F8}?TO1y@V1*$R%@)!(7FxB| zSWUYKPdlJ1!s8b)`S@HL&tYLc7hmJ{_PIT--hPMI?lD!YhYquwhvcEC7L0e2A-Ky} zCCr>TQ>YIb8h=gys3^nZ9&~tZ7Gg;rv(+w`J%UX%!-%buSgosuvFkT`-7t8dwQG|V zu3YkX304q)$mwvqt$jApFSmbKN!il7tc#c~Za<()2-2lq$0Q!9@d$-@oxsIn!+mTr zdUbnta+NS<3~=o=yIkgBl(s7eJ@-fg9ydjohMfzzbkw_J2HMvJeepTZp}jkr(4i&{ zUpuJNqmOpX#5+#%iKu4h%3U{e@auom@z~kN<)CxBiqP+Nj>B7f7~_cMk~78IJub6x z?dVpE(el454JISguA0b=W}|O*HH~g~9NLZwNW;bW(35N|a_%+YEh|_aH6BPgau)qz z9{!}5&BX6!F}b@g#N(O!*aQRdn0kUdKU8v|dXjvwaO;J!@IRr+?DY(S0nInN%r-F1 zxsE=UxKWrfxWPiNng)i{0AjAn&sP)i;J0WblHh+qQ88@Jcr4{>+DP%PI;Y;t*TIju?5?h%vzROSk}1+ zFSRo{=-S6TdiJB`sPyAz?ISp!~N$V|=+ z5J0scQ8DvlHlsM86=5Q73hp_R9v%KDvr3xve$6Ui%DKqg4!w=)ZsaCaSYgVx3^~4I zt=1#+r4sb@*D0V<4!-AJE-OJ=ggv4QGY-y}JRo`kBZZlxIw4l-XZ*;Ybw#M@>2iE+ zCtHB7Stj8tb~Z_<@C;hrHM4>Sqh^+$$y^vxe3)f2@sAwrK$=`Npgum~WKDR-HfAh7 z=wwSutm_4nMO<&Six!h{4h+wdj_%&B=2lo6IuU#hOTedZvTG2_I>C z`j^a++`lC=(U~s#%QJ~N9>)gJZd^;It7Pu<#&mRkPj)t0x0=Z&w8m)mc+CBSLtp`J ze7J?n#7+0H9CADxhZ=7d<`7p%t>(3OwgjK<=lEYYGQZN*3QZOfR>gkUo-M*M*h8s1 zU>hcDWI!*A>T_3^{yqRad|9_)FQ7ltRHCUsi0r)e}3)c0+rvDB# zih?W_7BGc3_)4P9f=`~)mEocZ?3Dk3RpH3>H^(sekuyxZZ&p0BCEItrm}yPIZlw!! zD8*ZQ*(_g1JM&EQmQIJw)@ODZ-PD@{-v+E{y+hb!wZXnD`*&p1CfDTYIDz^@D!HpqJD9s!JhKdTp$Af!-{BPq9MR7ogL(IxYv8b6c?^zxk3!{wM;QZt z7cq&r;Zdd(J-a;)Z`sWh;p*9}9%sj~X(@CxOcn9~;tmX(aNnIUi(lTt)TSFp^eWjI z(bCVev4EKry!bJu1|57O5kCkQWRpzBYg*;Te@L24K``5QAYgcGylxEsE@IZ;L%YFo z{q>_v8#?5T#ZNrSDahSNV}E>xw%84J#yf~lu_(B;@< zh64p|d?Ys8xBms^>r{Mgxh^i3m?z9=(L6-FJOLaFt4G*mcH{Fk;9`+m#7ylDFiSYe z^n0uu;jALM9bQ+zh|&gg@QF!mEVCJ(dzCB29T$0yb=k1_A}>IRb~a4Jhjua3@by11 zb!gTrdbHgeo8ooZ$doifZ^DVnSNbONYaJ5m? zGN6v`YJ9@W@`*~-HEZ!6tF9h5C9)hjs1)LT7M90buET~vHb%K3PP>)M!TTQM_1I9s zHsGcw**xEpN_NK9ylSCle6`Tg*)p%Ut7B1HckkjQy)Eq>-4Jtj=lKr&EBg~Rvw4%d zXYMd80FJqRJ?&-jhK83u1{$o!vnff{3I?|7^X(?# z3Ub6ki!aQqjQWh27IH>J-@8yIS{(iEI#@5=<^i!L$O(d_b;JQuI;`pMqhE;1MhnlrkXj2D?ak%)l3F&f0&EM?&GjxzWyxy z=b%VNHxb28R+MpEV?nI7yj5(v_g3za^oo z$6)P!k=3Jr{ZuwfCyB^!x5V5BF{nX~Y1gSs4g zA3gNhN9dQIuS8qEN;b-i+<<5oU9hP(D^77M@vBTm8tFDx(;dfI0gJ`nLRf=F^oM^P zO2Dg)u(9l&qRXN28xqXHkGF6s_^+RH*~sv95HgB2HD zxiP<3TNJeOtKuYY|9Y#-4G}W%Oi=TeB@hIPN2V{+IC`V$OM!!vrHJ16CU5t@GpT6n z9o(*)d{E2?!b)iIH;L%{m-Eq;Z?f?7f8qs@HHrS1-NvWWALn+(8N+ml+f*SrQENzx zYpX^!wIoeC#a0BSm9$Fuj}`_xBJ^k?%|Lu&ER#=07`=J(`*@v>`2luzv*|dQV>aP4 zN0`{8;5mm%Uu>awlcl>WnmZS_EuIIrEAdSZTna*=m!6TSw(GaG!PVv2g$@st;X8Te zUf44Cy}^~?;#fwY!D2kCjEPIO!I54H0uv)+cIR+(>cOI!jT>W`xACplV9#;>JRLVL zg5i8$U}jR+8=aUMhwnHJGY}?DBHmicb$&?+`26JB~}J4KpmTR|6{%LOPTIloIv${kpNp z`bA>A{9KQ=e4Ufw4@8=z+EqfMfPWavRHS&tDxty8LyunlI#-qgqAfYNX)BXBd7eB` zKqYXvZ8j0y5%8VCZyv3p?0ZwiNKX~vrp2(H)ZGhV5k;YrFbcU%QitHQ``N5m`H4tkv&>=SrBRW;&e!&}l#f{-<|NEN9u=$Md`-j*QEKYr%Pe=&3XU-?t zrrit4I@inasPNQSyyGxikAGjmuEhCIvfD=0_d)%hnmO%eyVq<3FP=JRu#~_-0#2{6 zpTQOZ8{UA~1>gyYPSPWW=&wdP58NQAKQN5<-{6Ylh<^t^F|!6X>3_V>7ST=KnGAkx z{r_gOaP?v?6{lEqDLCZ4J4>%n~wMIhI81~h4FY_ z0XqvXE@0>24hxLNiF4o@EhuE0v2z=5z$A2ynr0;6wQHFQeDEnq*fbd!j`&;#lW~b9#*IeH^b$sX4 zmhKw*Kw>$0>~8Y)wmp`GI6JsAJfs|r|Qs?S99^EUF;K`;(_JWh8*U0tQSmNKN{0pa3}R=^n45d@OEjy?cBja0yymF_XJuP_teeJ__6 zPuxq=)ihp=U*^ES*?un<7w7jVApDk%UvaQglY&JW8QX0^KfalUXFk9RB;uNQ#QHCB zjPLDu-J)CP)zt}*O`TFZew<*oZ8AfEfgIY0to<&B8-fdVi(7!q6&&&)w%~>sg$T(o zdUCUi5Fn!~!XQY9)82#pNd15=E1zVBMg>M@KwM;eeZ8+`KsUL*lJpLA7g-a83K&RO zMV3Icpi^|h{vcW?2E^?f#=1#y`7mH%YT%A1bd~s(J-Tc7GHhhEp)ANah9P$2@%O{- zTKI%6-gjoNZeAQ&2omzuMIj3LDu1erGu7J75KOTP&9y>T|KKJO5{1Hy?>MBpZuyRs z(;-8R&;LsIQ+)J2U4<}zK1Z&z*ADm|PyaTIA%KN&wiUl%1 ztyb`vuXMQy3TOpiJEF_;dEeLln#mg+pnj)Yw5_Ls@Ia+m7j*NIm7i@8aw1D|7T$kB z*U|>ZZ?DY*T_)b{v^gxI$tXbn7@~4Rrgeh@g4H6_*!$L1RZ015GK3^uAg4Da;wlmV zn@Ic%>Z4%82f9@J$VFXoy!3p{coKrh$TRwNmvRE~!wGAvN#3y>HSLBIAhgmJDDe#j4&KD5le!= zRkcPqk$KFvD!gtj_bx7Wa+SUfMcm^&uHVdYxfLRf?vnHwY;8SV4zsh>44s3==fhMp zJjnA&V$H1eD`g^ zaz#Ib1YlqhAq{M!#03(ubVnhSexf&?EysL0_Z;5(J)Uc{x*<6ZCtepU%pk4TPMsY& zu^M`tcDM1)ew)MXbwRosm;Ni0ga1;_-G+CRbMbL9J=*(umG7-`P8aL@uPW{zW0FZ0 zT5&&oZ*_2v zcnC5!?cid4Jv+Hx-BegbUE+`f!dNzOy$4E{P)TF9wYT4XdnKLom2xmpx&xEPY#-L+ zPc?($v^M*=&}Ht9oi{$2C^g!PGRu|0^6`kJIbH z`;Rllz84~c z#A!x8mxk`}#HYAi%Fx&S6t^Lk>A}|)=mg){<6IF4hB>_Y2AkDv?1vDcN9-`WJb=7w zcl2*CR#gd7e1fbn^g9SCDGlWOmt!{BxJJx34nd!^gOl_@U>xL|?}9+%FhfsZgmj$7Q}_SP8t7i4{bF zFTTJ{!`7#{T0G%JZZ>}PX$UOb|035-n3(DnCY`XSL6BbVDH$a~wSoVD(o&>az&l^$ zG9jG2vkiv-nPc2keEvl)3%xKdGrhOhqI!KJ}(k-M%wyUSO6yM8lav5s1wk9#DzC)+DqHquKLl5hwD}3;RXCRNU z?tgKwskdmrsSoO=DAj%0Z*y5;IWPK<8;6@-<|=TK*QTDwQa!r{Coqxa~GRgY;Yh{@ZCV)#LBMDqiviHy6LRl+8i6zLkS_ zyaAqL;#S3pjc_9dmh<0@C?d;bk?6@#DrEw>%N_6N?X($fF$ck%Xs75e-ADeOGM zHH36m8eZ&!H69k5VOV&Uo#oneVBYwNvs?-O4g81xdiyL_3=xda;ddE4h2SCN3czO` zft71p+`5EJ4FT7k;|eHU+c|C_aDDU~_a$Uj3kfLZZaxMwgIo>F-RGhm7& z)wp-LWhxc?qae$k@(C{H401$( z;NytTREr;+smn*jZ%u=c5|77Rg>B`PqX6;n&or#J@!39@Tr2Bfw~9d|Q%;H?lQy#z_uE82;R zW`U>Rew5w;VTE3m$EMMKEdlieOEh{{!iS&d^KkD=d_p29Ekja`$S}UB%+xan5*%=N za`iNOJ&-&#Ta-HzOMLUUd_^90&fDy;7np63NU{B5?_u7UxHRX`6UEg zx4p!VMe7ickG{m4@Q-#w+zDz-9`$h9%Y3!;@Zp#FMttgJzLXMu{4x;PASi+i1A1Ta zDgKRE{Pk;mGXCcGd`t-bH^Mn9OcL}lH(w59~Aw7!XTalASdcz-qz4732;X6mEii2{2=%> zqMe?AAgDx-nD}}HsCxqT@HCnm5Gn#qBlE$cJn&tc6=6)lPfy;Kvno&-?8oog_KLS# z-5$5eNS^kt7a?;=Ed`uVYcGWN>4RGNgbPm^gBykL3^{Z_#xWP2KEzE8Ru>?cpf1Io z(t`^7N}8M zL1BU9&~5bu9reg6OOAWwHa=UH9N}I>2}q@zElUy>Y%T{ z2d6#UWE|N6-6IRp(S0it{sPa~NN8&o)Gh~aB9lV4Wk=+8f z!yXm8!icOE1!tYLO>sd<+MGy=!YV#s8;(l0L^QEDBcdS!L+}XPgHf_9DvE4~FvSNP zb7x1%@nU{vNd&EN^DHJaQ@iubg*g#BuM3coW>=JQoh*#pc`K|o3m`WFumWuv|5yak zzQC>-*oEiQ^ba^R&E$0{aF660;n|%?N`QChGm5p@p`|PHH2O_q5|7|z@`Yj7))3jc zhTY&(L@6P8%RgPm-Dolw(Ij6BQT|@ z_ox(pCN^!hHZx^^ii+QF5;I5a>dNk^jLIB`w|{W%?5MbvWTZzJiaFjs|0|8!z4mx& z>IerxMKHjk_Vg@+x2!Zdjhh4Y>PWT77KqKuG}i%Q&-cdXMwk@%+APSdYYK&4iOY{L zQ~mhRXgVIgo1nheDx)ZS7+s>-)jt>wOEfhl%&r*VNxmWg%X?Jp5@RzW%z{>{4LpH} z%=V=xqRVV*q%qifjLp&*gMH}$13AXVO^9q1tq^AbOzj-V)VoDXPY+&qlr7L?or_*c zD+zx6Q)M9@%@sAJ7e`>)lwS5Nnc|@nY@sICsS##>D{MaC>qa#yEjmMlwW-x6iq83g zFT#YMBm2_z=z3~KggN4Oa-$GWkIp7XTAYaM7?BlO10G{jXKAm(!QWX4uO;y646Yg3 z7-jLI@Ry04EFWogm-(%50emUU>5qEfgxd@@J%Y8&w>sy*TQE`e;aWaDLLauZc6WD2 z#p`N{LESf#sc9gm#SWQ1(H#}TxWudotCi#@N5$+%36UI>cEA`!#p)oJ8evKRoY3Ne zH=Lqkx6lyL!E4Hj z5Snc)BW;ZShM4v)PFn!bXf(aDl&}xfjY52g&WTa6Mn6a~MA(i1#RA~fXyiojZ8`N& zpJJz7o2=_SWKW7}e(TY2Mx@;`>La}#zEl{=iI*Q1{pBAtyCesG$!IJ@Yu zXj&3{nk_rRhR_Y~)kZNI320JgYMZtZt^kj!6$S&Kfx*6_mV^o9>vs_bc{L>IVPm!e zHZm$f8xyht52s{u0!JF+32C^F3rS)KDukU79sWHoGjS0vNwpo;xHCur%{bffq z1aN!62IZtclzbn}$yfIc6#AZ?Zu5ZhOIu23UKme9p@+4{8lBD~({M^$EQk|qq{=UC zxsK)<#;clpr#JwB4%cva^7ibJ89eA@IbZINF^69mNbVTjCzNLex2-V1CjqUTtJX55 z%POteqDn`y_0nsXD%o$fbTwI-D8XpMR74>xVeM)LaH|+}=FSeyu2a!$WrYisYEdx_ zo8XlBRgTzaM$4tN6}Gc3lvYd&+gYHQcKeo6VX8VcImbj8-*IInVT31}V^7aqf;c9Z zVTGS8)D)^WFLA)mP3iR9%^ZB>6#nKdF26UwXG3ZI4RY4v)*Eh5)Ty`ongb3g~cP#%jcFJqGvsh{j=vp@3l!x9i>8FGvhe(I?+I^U{73k;7b;9UGrI6frjd-Rk%vilF zhz!LlEeJqFDLQkJgps9iQJmJm=T-L1kzUYgXy~)Td$WG*qX6G&B9Kf8S&EmIF&See zjA_j*3Ej0wv=4X&{Qxf&yxW3?1{u*5R5kDl7{UI?uvI_HAi$UkzZQj`zn&&D1xBU9 zs!?Gj)e6IiLir@9kqVQEz{FoeewUT#bXPS6epU-X9p2DDD^^X%!_V^txZq3v6n^Li zKQ7*nF~fiPl0Q>Q$iqR9s0rdXZ}4LXXsJdX=Ww-^nKFWmB9y8kkOnqSe`^$uROTmB ze6wJTk<`o=U-Dz;hQl5O&Q=PPAS~_(6Hb1h(S(qegBYlTjDqM3vNY-a$rgoWKoi_?L}6!PPzE!3n7#rOE>5)lA;>b3fecxa=+JOOGz?`RGe!2Y5~BP$^L}|FI`Hnj+DXlmuXD z@WMvh*tpvC?fSsFnaJz*sc;YBYo;KnIu=Wy?@$ zawJ|wAv3B0R8;h(;FQru0%#Nsv!Y0p(Ifyp(Xe7Q*oh)4;7mf-Xr)iXVoVfz0xHpH zn{Jb^>c|{}=02GZfFRMZqfqpS)T#^@(dr}u6$$PnKQ^RRd*+Qsa8O*xNInz@qG3v- zSr8D&Xbyn-_!b-};$tL>sT$Kj1>OY^9&}k?H6Mi7C;%=rdRrzAKAb2r5OjqWX(+NHKnhR_ z4ZTBP6ahlOO@wZzvXtR469H-fNoY(+$@d5yVA4&1h|n0|(P)T3ivWMnFe)|ZLx2{r z4jPL90-Qtev>{Rgut8%)WbZ~@K|nERH3kTV(TxFQK|?h)xI#cRz$a*QXAtCI*?@c95GB-b^zbR`k4HeG2ZUBmlRh(~A91Fb{aTw|RYoig{+(H!~Y@cX(}emuYf z65<+N9wr$cAcyR?KNS(M60*g~nQvNiYG|rEP+7^ysie83cI3RaKSHWX3XVs(oOXZ- zB(Xz<4Qihzu!A?Cpp12>KM+KymaPsnE2pPJgD@c+R8rHyY;r@*Yy=C{JhZ}~Ei_TB zy1NCjlrKjoofVcO%d9ypu*HEfsAiZ0OdzEkx`6~q5t2?0kV5`glQblE>?aL`Ka~S% zP>UgnVn10Tg3NGn$ebII6_)Bk8o1J5FOZ(}M6TY%N(pp8O zl_epyMy7Y+o0oiclRqe|mdOoz!&wqzbQTv94U`M=lx5zcc=W-x5>P0JLr~P03hOB= z8lx&KtPKiRX$zwDFP9c75#rGejOJ}C%`FY(Ju3MsDKW7uM@0;^RI5~fmQa}+$~q{q z8ayCSS#cyn(`F%QRP6hbFDH3ZMWRrm;GC&cACjadzeJ(+M<`3rBNfwG>6S~s=S}Cn&*@nhs355P77^3d{R@Qma~|OYZi_}Xa>_ypQF)V z!HK|t=8#S_Xo?&zHz_p<$;fHSEC`-kYO)7dNr^~>#f0F@qrb;TXB{g5Lu_%lAmtUD za8w*;xj{-5oNNpwYYfdZj%YJ9#~8w6EDx3pNvwOGhc5%X_7(q}@5Bv$)%|?Ug!=JQ z@EiBWX23_>#|rSzky*sseN(<0Yl^jW!9S?i+0xYk9{?rDP{H9OpGby(pbY-VXF=qz zlk_|6>#YMdv#idIlRM$-8eLu|`JyNNN88B9%G4gxFAS1TeB7X1CA&KUtQe>;M1& delta 6590 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 && $config->ipv6RespSupport === true) { + $log->debug('RESP MQ Setting socket option for IPv6 to TRUE'); $responder->setSockOpt(\ZMQ::SOCKOPT_IPV6, true); } @@ -66,6 +67,7 @@ function exception_error_handler($severity, $message, $file, $line) { // Set PUB socket options if (isset($config->ipv6PubSupport) && $config->ipv6PubSupport === true) { + $log->debug('Pub MQ Setting socket option for IPv6 to TRUE'); $publisher->setSockOpt(\ZMQ::SOCKOPT_IPV6, true); } From 025bc2880e402bc22ffdbe50344983bc92dca86b Mon Sep 17 00:00:00 2001 From: Dan Garner Date: Fri, 5 Jan 2018 13:54:58 +0000 Subject: [PATCH 3/8] First pass for QOS. xibosignage/xibo#1368 --- .gitignore | 3 +- Dockerfile | 29 +++++++++++++ README.md | 2 +- Vagrantfile | 19 --------- bin/xmr.phar | Bin 477638 -> 486661 bytes box.json | 2 +- build.sh | 14 +++++++ composer.lock | 46 ++++++++++----------- config.json | 8 ++-- docker-compose.yml | 13 ++++++ entrypoint.sh | 36 ++++++++++++++++ index.php | 70 +++++++++++++++++++++++++------ tests/cmsSend.php | 98 ++++++++++++++++++++++++++++++++++++++++---- tests/playerSub.php | 17 ++++---- 14 files changed, 281 insertions(+), 76 deletions(-) create mode 100644 Dockerfile delete mode 100644 Vagrantfile create mode 100755 build.sh create mode 100644 docker-compose.yml create mode 100755 entrypoint.sh diff --git a/.gitignore b/.gitignore index d38af3e..64e2bcd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ vendor/ -.project/ -.vagrant/ .idea/ +config.json \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1e76f98 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM php:7.0-cli +MAINTAINER Spring Signage Ltd + +ENV XMR_DEV_MODE false +ENV XMR_DEBUG false +ENV XMR_QUEUE_POLL 5 +ENV XMR_QUEUE_SIZE 10 +ENV XMR_IPV6RESPSUPPORT false +ENV XMR_IPV6PUBSUPPORT false + +RUN apt-get -y update && \ + apt-get -y install libzmq-dev + +# ZMQ +RUN pecl install zmq-beta && \ + docker-php-ext-enable zmq + +EXPOSE 9505 50001 + +# Copy up the various provisioning scripting +RUN mkdir -p /opt/xmr + +# Copy XMR into a convenient folder +COPY . /opt/xmr + +RUN chown -R nobody /opt/xmr && chmod 700 /opt/xmr/entrypoint.sh + +# Start XMR +CMD ["/opt/xmr/entrypoint.sh"] \ No newline at end of file diff --git a/README.md b/README.md index e3716aa..ba378a4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Introduction Xibo - Digital Signage - http://www.xibo.org.uk -Copyright (C) 2006-2015 Daniel Garner and Contributors. +Copyright (C) 2006-2017 Spring Signage Ltd and Contributors. This is the Xibo Message Relay (XMR) repository. diff --git a/Vagrantfile b/Vagrantfile deleted file mode 100644 index 25ddba3..0000000 --- a/Vagrantfile +++ /dev/null @@ -1,19 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! -VAGRANTFILE_API_VERSION = "2" - -$ip = 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 delta 5229 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 /usr/local/etc/php/php.ini; curl -LSs https://box-project.github.io/box2/installer.php | php; php box.phar build; rm box.phar" + +docker build -t xmr-dev $PWD + +#docker rmi composer +#docker rmi php:7.0-cli \ No newline at end of file diff --git a/composer.lock b/composer.lock index d9b4ae2..51bb541 100644 --- a/composer.lock +++ b/composer.lock @@ -9,21 +9,24 @@ "packages": [ { "name": "evenement/evenement", - "version": "v2.0.0", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/igorw/evenement.git", - "reference": "f6e843799fd4f4184d54d8fc7b5b3551c9fa803e" + "reference": "6ba9a777870ab49f417e703229d53931ed40fd7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/igorw/evenement/zipball/f6e843799fd4f4184d54d8fc7b5b3551c9fa803e", - "reference": "f6e843799fd4f4184d54d8fc7b5b3551c9fa803e", + "url": "https://api.github.com/repos/igorw/evenement/zipball/6ba9a777870ab49f417e703229d53931ed40fd7a", + "reference": "6ba9a777870ab49f417e703229d53931ed40fd7a", "shasum": "" }, "require": { "php": ">=5.4.0" }, + "require-dev": { + "phpunit/phpunit": "^6.0||^5.7||^4.8.35" + }, "type": "library", "extra": { "branch-alias": { @@ -42,8 +45,7 @@ "authors": [ { "name": "Igor Wiedler", - "email": "igor@wiedler.ch", - "homepage": "http://wiedler.ch/igor/" + "email": "igor@wiedler.ch" } ], "description": "Événement is a very simple event dispatching library for PHP", @@ -51,20 +53,20 @@ "event-dispatcher", "event-emitter" ], - "time": "2012-11-02 14:49:47" + "time": "2017-07-17 17:39:19" }, { "name": "monolog/monolog", - "version": "1.22.0", + "version": "1.23.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "bad29cb8d18ab0315e6c477751418a82c850d558" + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bad29cb8d18ab0315e6c477751418a82c850d558", - "reference": "bad29cb8d18ab0315e6c477751418a82c850d558", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", "shasum": "" }, "require": { @@ -85,7 +87,7 @@ "phpunit/phpunit-mock-objects": "2.3.0", "ruflin/elastica": ">=0.90 <3.0", "sentry/sentry": "^0.13", - "swiftmailer/swiftmailer": "~5.3" + "swiftmailer/swiftmailer": "^5.3|^6.0" }, "suggest": { "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", @@ -129,7 +131,7 @@ "logging", "psr-3" ], - "time": "2016-11-26 00:15:39" + "time": "2017-06-19 01:22:40" }, { "name": "psr/log", @@ -180,32 +182,30 @@ }, { "name": "react/event-loop", - "version": "v0.4.2", + "version": "v0.4.3", "source": { "type": "git", "url": "https://github.com/reactphp/event-loop.git", - "reference": "164799f73175e1c80bba92a220ea35df6ca371dd" + "reference": "8bde03488ee897dc6bb3d91e4e17c353f9c5252f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/event-loop/zipball/164799f73175e1c80bba92a220ea35df6ca371dd", - "reference": "164799f73175e1c80bba92a220ea35df6ca371dd", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/8bde03488ee897dc6bb3d91e4e17c353f9c5252f", + "reference": "8bde03488ee897dc6bb3d91e4e17c353f9c5252f", "shasum": "" }, "require": { "php": ">=5.4.0" }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, "suggest": { "ext-event": "~1.0", "ext-libev": "*", "ext-libevent": ">=0.1.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.5-dev" - } - }, "autoload": { "psr-4": { "React\\EventLoop\\": "src" @@ -220,7 +220,7 @@ "asynchronous", "event-loop" ], - "time": "2016-03-08 02:09:32" + "time": "2017-04-27 10:56:23" }, { "name": "react/zmq", diff --git a/config.json b/config.json index af063f6..4a4170c 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,9 @@ { - "listenOn": "tcp://127.0.0.1:50001", - "pubOn": ["tcp://*:9505"], - "debug": false, + "listenOn": "tcp://172.26.0.2:50001", + "pubOn": ["tcp://172.26.0.2:9505"], + "queuePoll": , + "queueSize": , + "debug": true, "ipv6RespSupport": false, "ipv6PubSupport": false } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..dfe5473 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +version: "3" + +services: + xmr: + image: xmr-dev + volumes: + - ./:/opt/xmr + ports: + - "9506:9505" + - "50001:50001" + environment: + XMR_DEBUG: "true" + XMR_DEV_MODE: "false" \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..7d61b00 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +# Get our running IP address +ip=$(ip -f inet -o addr show eth0|cut -d\ -f 7 | cut -d/ -f 1) + +if [ "$XMR_DEV_MODE" == "false" ] +then + # Write config.json + echo '{' > /opt/xmr/bin/config.json + echo ' "listenOn": "tcp://'$ip':50001",' >> /opt/xmr/bin/config.json + echo ' "pubOn": ["tcp://'$ip':9505"],' >> /opt/xmr/bin/config.json + echo ' "queuePoll": '$XMR_QUEUE_POLL',' >> /opt/xmr/bin/config.json + echo ' "queueSize": '$XMR_QUEUE_SIZE',' >> /opt/xmr/bin/config.json + echo ' "debug": '$XMR_DEBUG',' >> /opt/xmr/bin/config.json + echo ' "ipv6RespSupport": '$XMR_IPV6RESPSUPPORT',' >> /opt/xmr/bin/config.json + echo ' "ipv6PubSupport": '$XMR_IPV6PUBSUPPORT >> /opt/xmr/bin/config.json + echo '}' >> /opt/xmr/bin/config.json + + /bin/su -s /bin/bash nobody -c 'php /opt/xmr/bin/xmr.phar' +fi + +if [ "$XMR_DEV_MODE" == "true" ] +then + # Write config.json + echo '{' > /opt/xmr/config.json + echo ' "listenOn": "tcp://'$ip':50001",' >> /opt/xmr/config.json + echo ' "pubOn": ["tcp://'$ip':9505"],' >> /opt/xmr/config.json + echo ' "queuePoll": '$XMR_QUEUE_POLL',' >> /opt/xmr/config.json + echo ' "queueSize": '$XMR_QUEUE_SIZE',' >> /opt/xmr/config.json + echo ' "debug": '$XMR_DEBUG',' >> /opt/xmr/config.json + echo ' "ipv6RespSupport": '$XMR_IPV6RESPSUPPORT',' >> /opt/xmr/config.json + echo ' "ipv6PubSupport": '$XMR_IPV6PUBSUPPORT >> /opt/xmr/config.json + echo '}' >> /opt/xmr/config.json + + /bin/su -s /bin/bash nobody -c 'php /opt/xmr/index.php' +fi \ No newline at end of file diff --git a/index.php b/index.php index 8f1b208..d827504 100644 --- a/index.php +++ b/index.php @@ -24,32 +24,40 @@ function exception_error_handler($severity, $message, $file, $line) { } set_error_handler("exception_error_handler"); -$config = 'config.json'; - -if (!file_exists('config.json')) - $config = (Phar::running(false) == '') ? __DIR__ : dirname(Phar::running(false)) . '/config.json'; +// Decide where to look for the config file +$dirname = (Phar::running(false) == '') ? __DIR__ : dirname(Phar::running(false)); +$config = $dirname . '/config.json'; if (!file_exists($config)) - throw new InvalidArgumentException('Missing ' . $config . ' file, please create one in the same folder as the application'); + throw new InvalidArgumentException('Missing ' . $config . ' file, please create one in ' . $dirname); -chdir(dirname($config)); +$configString = file_get_contents($config); +$config = json_decode($configString); -$config = json_decode(file_get_contents($config)); +if ($config === null) + throw new InvalidArgumentException('Cannot decode config file ' . json_last_error_msg() . ' config string is [' . $configString . ']'); if ($config->debug) $logLevel = \Monolog\Logger::DEBUG; else $logLevel = \Monolog\Logger::WARNING; +// Queue settings +$queuePoll = (property_exists($config, 'queuePoll')) ? $config->queuePoll : 5; +$queueSize = (property_exists($config, 'queueSize')) ? $config->queueSize : 10; + // Set up logging to file $log = new \Monolog\Logger('xmr'); -$log->pushHandler(new \Monolog\Handler\StreamHandler('log.txt', $logLevel)); $log->pushHandler(new \Monolog\Handler\StreamHandler(STDOUT, $logLevel)); $log->info(sprintf('Starting up - listening for CMS on %s.', $config->listenOn)); try { - $loop = React\EventLoop\Factory::create(); + $loop = \React\EventLoop\Factory::create(); + /** + * ZMQ context wraps the PHP implementation. + * @var \ZMQContext $context + */ $context = new React\ZMQ\Context($loop); // Reply socket for requests from CMS @@ -76,12 +84,15 @@ function exception_error_handler($severity, $message, $file, $line) { $publisher->bind($pubOn); } + // Create an in memory message queue. + $messageQueue = []; + // REP $responder->on('error', function ($e) use ($log) { $log->error($e->getMessage()); }); - $responder->on('message', function ($msg) use ($log, $responder, $publisher) { + $responder->on('message', function ($msg) use ($log, $responder, $publisher, &$messageQueue) { try { // Log incoming message @@ -102,9 +113,16 @@ function exception_error_handler($severity, $message, $file, $line) { // Respond to this message $responder->send(true); - // Push message out to subscribers - $publisher->sendmulti([$msg->channel, $msg->key, $msg->message]); - //$publisher->send('cms ' . $msg); + // Decide whether we should queue the message or send it immediately. + if (isset($msg->qos) && $msg->qos != 10) { + // Queue for the periodic poll to send + $log->debug('Queuing'); + $messageQueue[] = $msg; + } else { + // Send Immediately + $log->debug('Sending Immediately'); + $publisher->sendmulti([$msg->channel, $msg->key, $msg->message]); + } } catch (InvalidArgumentException $e) { // Return false @@ -114,6 +132,30 @@ function exception_error_handler($severity, $message, $file, $line) { } }); + // Queue Processor + $log->debug('Adding a queue processor for every ' . $queuePoll . ' seconds'); + $loop->addPeriodicTimer($queuePoll, function() use ($log, $publisher, &$messageQueue, $queueSize) { + // Is there work to be done + if (count($messageQueue) > 0) { + $log->debug('Queue Poll - work to be done.'); + // Order the message queue according to QOS + usort($messageQueue, function($a, $b) { + return ($a->qos === $b->qos) ? 0 : ($a->qos < $b->qos) ? -1 : 1; + }); + + // Send up to X messages. + for ($i = 0; $i < $queueSize; $i++) { + // Pop an element + $msg = array_pop($messageQueue); + + // Send + $publisher->sendmulti([$msg->channel, $msg->key, $msg->message]); + + $log->debug('Popped ' . $i . ' from the queue, new queue size ' . count($messageQueue)); + } + } + }); + // Periodic updater $loop->addPeriodicTimer(30, function() use ($log, $publisher) { $log->debug('Heartbeat...'); @@ -127,3 +169,5 @@ function exception_error_handler($severity, $message, $file, $line) { $log->error($e->getMessage()); $log->error($e->getTraceAsString()); } + +// This ends - causing Docker to restart if we're in a container. \ No newline at end of file diff --git a/tests/cmsSend.php b/tests/cmsSend.php index e031c45..d0d2465 100644 --- a/tests/cmsSend.php +++ b/tests/cmsSend.php @@ -1,20 +1,104 @@ setIdentity('player1', $publicKey)->send($config->listenOn); -echo 'Reply received:' . $reply . PHP_EOL; +try { + + // Queue up a bunch of messages to see what happens + for ($i = 0; $i < 1; $i++) { + + // Reference params + $message = null; + $eKeys = null; + + // Encrypt a message + openssl_seal($i . ' - QOS1', $message, $eKeys, [$publicKey]); + + // Create a message and send. + send($config->listenOn, [ + 'channel' => $identity, + 'key' => base64_encode($eKeys[0]), + 'message' => base64_encode($message), + 'qos' => 10 + ]); + + usleep(100); + } + +} catch (Exception $e) { + echo $e->getMessage() . PHP_EOL; +} + +openssl_free_key($publicKey); + +/** + * @param $connection + * @param $message + * @return bool|string + * @throws ZMQSocketException + */ +function send($connection, $message) +{ + echo 'Sending to ' . $connection . PHP_EOL; + + // Issue a message payload to XMR. + $context = new \ZMQContext(); + + // Connect to socket + $socket = new \ZMQSocket($context, \ZMQ::SOCKET_REQ); + $socket->connect($connection); + + // Send the message to the socket + $socket->send(json_encode($message)); + + // Need to replace this with a non-blocking recv() with a retry loop + $retries = 15; + $reply = false; + + do { + try { + // Try and receive + // if ZMQ::MODE_NOBLOCK/MODE_DONTWAIT is used and the operation would block boolean false + // shall be returned. + $reply = $socket->recv(\ZMQ::MODE_DONTWAIT); + + echo 'Received ' . var_export($reply, true) . PHP_EOL; + + if ($reply !== false) + break; + + } catch (\ZMQSocketException $sockEx) { + if ($sockEx->getCode() !== \ZMQ::ERR_EAGAIN) + throw $sockEx; + } + + usleep(100000); + + } while (--$retries); + + // Disconnect socket + //$socket->disconnect($connection); -$reply = (new \Xibo\XMR\CollectNowAction())->setIdentity('unknown', $publicKey)->send($config->listenOn); -echo 'Reply received:' . $reply . PHP_EOL; + return $reply; +} \ No newline at end of file diff --git a/tests/playerSub.php b/tests/playerSub.php index 040a1fe..3b6a93d 100644 --- a/tests/playerSub.php +++ b/tests/playerSub.php @@ -1,8 +1,12 @@ pubOn[0] . PHP_EOL; - $fp = fopen('key.pem', 'r'); $privateKey = openssl_get_privatekey(fread($fp, 8192)); fclose($fp); @@ -31,7 +34,7 @@ $sub->on('messages', function ($msg) use ($identity, $privateKey) { try { - echo 'Received: ' . json_encode($msg) . PHP_EOL; + echo '[' . date('Y-m-d H:i:s') . '] Received: ' . json_encode($msg) . PHP_EOL; if ($msg[0] == "H") return; @@ -51,12 +54,12 @@ $message = base64_decode($msg[2]); if (!openssl_open($message, $opened, $key, $privateKey)) - throw new \Xibo\XMR\PlayerActionException('Encryption Error'); + throw new Exception('Encryption Error'); - echo 'Message: ' . $opened; + echo 'Message: ' . $opened . PHP_EOL; } catch (InvalidArgumentException $e) { - echo $e->getMessage(); + echo $e->getMessage() . PHP_EOL; } }); From 914cf80d9fb9fb86c6592c1c2e822b3d8c91f15e Mon Sep 17 00:00:00 2001 From: Dan Garner Date: Fri, 5 Jan 2018 13:57:18 +0000 Subject: [PATCH 4/8] Remove config.json from repository xibosignage/xibo#1368 --- config.json | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 config.json diff --git a/config.json b/config.json deleted file mode 100644 index 4a4170c..0000000 --- a/config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "listenOn": "tcp://172.26.0.2:50001", - "pubOn": ["tcp://172.26.0.2:9505"], - "queuePoll": , - "queueSize": , - "debug": true, - "ipv6RespSupport": false, - "ipv6PubSupport": false -} From a29672606d84725d6bcc565b4b17566c9647a43e Mon Sep 17 00:00:00 2001 From: Dan Garner Date: Fri, 5 Jan 2018 14:43:05 +0000 Subject: [PATCH 5/8] Switch to alpine and full build test system xibosignage/xibo#1368 --- Dockerfile | 23 ++++++++--------------- Dockerfile-tests | 23 +++++++++++++++++++++++ bin/xmr.phar | Bin 486661 -> 486661 bytes build.sh | 2 -- docker-compose.yml | 11 ++++++----- entrypoint.sh | 43 ++++++++++++------------------------------- tests/cmsSend.php | 2 +- tests/playerSub.php | 2 +- 8 files changed, 51 insertions(+), 55 deletions(-) create mode 100644 Dockerfile-tests diff --git a/Dockerfile b/Dockerfile index 1e76f98..f78fb50 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,29 +1,22 @@ -FROM php:7.0-cli +FROM alpine:3.6 MAINTAINER Spring Signage Ltd -ENV XMR_DEV_MODE false ENV XMR_DEBUG false ENV XMR_QUEUE_POLL 5 ENV XMR_QUEUE_SIZE 10 ENV XMR_IPV6RESPSUPPORT false ENV XMR_IPV6PUBSUPPORT false -RUN apt-get -y update && \ - apt-get -y install libzmq-dev - -# ZMQ -RUN pecl install zmq-beta && \ - docker-php-ext-enable zmq +RUN apk update && apk upgrade && apk add tar php7 curl php7-zmq php7-phar php7-json && rm -rf /var/cache/apk/* EXPOSE 9505 50001 -# Copy up the various provisioning scripting -RUN mkdir -p /opt/xmr - -# Copy XMR into a convenient folder -COPY . /opt/xmr +COPY ./entrypoint.sh /entrypoint.sh +COPY ./bin/xmr.phar /opt/xmr/xmr.phar -RUN chown -R nobody /opt/xmr && chmod 700 /opt/xmr/entrypoint.sh +RUN chown -R nobody /opt/xmr && chmod 755 /entrypoint.sh # Start XMR -CMD ["/opt/xmr/entrypoint.sh"] \ No newline at end of file +USER nobody + +CMD ["/entrypoint.sh"] \ No newline at end of file diff --git a/Dockerfile-tests b/Dockerfile-tests new file mode 100644 index 0000000..0f1811d --- /dev/null +++ b/Dockerfile-tests @@ -0,0 +1,23 @@ +FROM alpine:3.6 +MAINTAINER Spring Signage Ltd + +ENV XMR_DEBUG false +ENV XMR_QUEUE_POLL 5 +ENV XMR_QUEUE_SIZE 10 +ENV XMR_IPV6RESPSUPPORT false +ENV XMR_IPV6PUBSUPPORT false + +RUN apk update && apk upgrade && apk add tar php7 curl php7-zmq php7-phar php7-json php7-openssl && rm -rf /var/cache/apk/* + +EXPOSE 9505 50001 + +COPY ./entrypoint.sh /entrypoint.sh +COPY ./bin/xmr.phar /opt/xmr/xmr.phar +COPY . /opt/xmr + +RUN chown -R nobody /opt/xmr && chmod 755 /entrypoint.sh + +# Start XMR +USER nobody + +CMD ["/entrypoint.sh"] \ No newline at end of file diff --git a/bin/xmr.phar b/bin/xmr.phar index c3cf49d3d90483bf3c86847855699e1d45665ea3..6aa428d8a15dc1cb84886c22af78eeb0ef26a869 100755 GIT binary patch delta 1325 zcmX|BYfMvT82;MA*V2|=pcgJ}DWxrKp`ylwX;qjP4BCqE0*J!Iy91_1G$=7@43UY6 z#*^$!wwW1ki7o@8jUxWg7>z;QVvLF6)F?3qW4t69w;6Tc`yA(wFHhe0Jn#EH&-aGL+;+0Dz$mH6j#k7IHam2c(0m6kWeomIHImMns-;#wW}FBFsb2J>34OR6xZ00 zY!%6-qmMO`)m0*S({-|?k89to#fMz~*v8GfLtVyXsU7ek=53}w}m)7b_ z<@)X1$x9uedsD${ORWWOo0G9i8-Hn(@*Jh|z$tF#)f~JKUkE}#FI4sD4t^2fZsQre zDFo7A9Ja=27t`#$TDTk0!dAHsgMQQ@dZ}w5N>$o71ifj{%=PsYtOAq^LVxarh*gvDom|f4>;m z(=H5DC@vEwG&pX8$d9I_5Hgg?*xK@>Te3znrETUIwL5Qy)?7<9D5rglU0ZXpLh3V> z%0IMm3$IXg4qE0C-D8ErRx7mpX~mduhO$$e*y+mQ-uln|{c_Gap2<7Yu+s+_Ff$=@ z3HA9oa|40Zwu#_-TPwjQ8L@wkV%f(%5U5J(_(C=DCbsjgETitLl}bQ_ zYw<#t$gh@hz1+Eq+bsj)ouQA1aMZ)q_hGlh3%ku;^c(a-V=#Xa8qqzqzi96IzmZYy zKPa~UM%n(OeB4yb2MygmL~ncv55MTcNAgXm7*v;ds~F%jV&He zQA;tb{8o(QNU>ri3b`%Oe4^}&76{mxjP6QCRpO|{(TI~GPO3QkOfsq+SLV9e@=wdf cug=A9Z2w@o6z%w<^Va5L;_t?0Oi4`n5A-&WkN^Mx delta 1325 zcmX|BZA?>V6n@*n+tLU}7{Ra+!qn(6 zm`J?I?nFmsL`~ETh&D>t52n#9b;+_HOC~zaMwSJ$h$b4%mZ|S~uJYr}lXLEK&Uv2m z-g}QsI*&{`N2*ln#33oFT1RkJRY&lj>LY@fdIQ0by3v?8RNc^}X6)3Grf;S1)MZjs zV?nZABwNn^sgcZ%63LyalTD*sEBB3Z18>zaCd$V(>#2)5sfJ)zQZ4Eltc?A?`nQ$R zUVW+D_yxD~QXA;*WbitZ>%i-=Gj^-vn`SA`Rw|EQ<>|bJgBRfSAo%n`)v#`GR)DjU zXYiH)NDnw{&C_n8*(bDcH?4)OavcVJtwS`UYa&W@%EtsFDbURIjTCLuZ^Eb=3uBkZ zFWr{r=D+hg!EJm(vFSD_x(&5d@{0lO<{2@u&)7i8zm1@jrPfn4kg7QRE1R*%RQJEL z299?L0~LzPSQ;8!OoPbRX+et4?m>6^hP;X)V!RW;kp&L(9)*j0t8aJGF?NZl4-yeAnMA=d|%m-kXA*KFolb z#hII_&za2q1ZK+tf@79;f;Sc{q0YLIqPP{iu-Y)O#kK(gD-DdXJyH}i9@*f*VaGjv zZr?(65A7&ekcD~uS(TK$pS6m>n;k=!&+-_%|LeG2B9}nT2M>~Iq-4ZwKwz|2=d1kGGuQ z6Ymm&bKVsM)7~ cK2&?Rr(c!ZG2^U`-Si$^DE@A2)w0;Kx6!Wa<^TWy diff --git a/build.sh b/build.sh index ea22d75..c4f2548 100755 --- a/build.sh +++ b/build.sh @@ -8,7 +8,5 @@ docker run --rm --name xmr-build \ -w /usr/src/myapp php:7.0-cli \ /bin/bash -c "echo 'phar.readonly = Off' > /usr/local/etc/php/php.ini; curl -LSs https://box-project.github.io/box2/installer.php | php; php box.phar build; rm box.phar" -docker build -t xmr-dev $PWD - #docker rmi composer #docker rmi php:7.0-cli \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index dfe5473..b9e7ba8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,12 +2,13 @@ version: "3" services: xmr: - image: xmr-dev - volumes: - - ./:/opt/xmr + build: + context: . + dockerfile: Dockerfile-tests + ports: - "9506:9505" - "50001:50001" + environment: - XMR_DEBUG: "true" - XMR_DEV_MODE: "false" \ No newline at end of file + XMR_DEBUG: "true" \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index 7d61b00..49b122a 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,36 +1,17 @@ -#!/usr/bin/env bash +#!/bin/sh # Get our running IP address ip=$(ip -f inet -o addr show eth0|cut -d\ -f 7 | cut -d/ -f 1) -if [ "$XMR_DEV_MODE" == "false" ] -then - # Write config.json - echo '{' > /opt/xmr/bin/config.json - echo ' "listenOn": "tcp://'$ip':50001",' >> /opt/xmr/bin/config.json - echo ' "pubOn": ["tcp://'$ip':9505"],' >> /opt/xmr/bin/config.json - echo ' "queuePoll": '$XMR_QUEUE_POLL',' >> /opt/xmr/bin/config.json - echo ' "queueSize": '$XMR_QUEUE_SIZE',' >> /opt/xmr/bin/config.json - echo ' "debug": '$XMR_DEBUG',' >> /opt/xmr/bin/config.json - echo ' "ipv6RespSupport": '$XMR_IPV6RESPSUPPORT',' >> /opt/xmr/bin/config.json - echo ' "ipv6PubSupport": '$XMR_IPV6PUBSUPPORT >> /opt/xmr/bin/config.json - echo '}' >> /opt/xmr/bin/config.json +# Write config.json +echo '{' > /opt/xmr/config.json +echo ' "listenOn": "tcp://'$ip':50001",' >> /opt/xmr/config.json +echo ' "pubOn": ["tcp://'$ip':9505"],' >> /opt/xmr/config.json +echo ' "queuePoll": '$XMR_QUEUE_POLL',' >> /opt/xmr/config.json +echo ' "queueSize": '$XMR_QUEUE_SIZE',' >> /opt/xmr/config.json +echo ' "debug": '$XMR_DEBUG',' >> /opt/xmr/config.json +echo ' "ipv6RespSupport": '$XMR_IPV6RESPSUPPORT',' >> /opt/xmr/config.json +echo ' "ipv6PubSupport": '$XMR_IPV6PUBSUPPORT >> /opt/xmr/config.json +echo '}' >> /opt/xmr/config.json - /bin/su -s /bin/bash nobody -c 'php /opt/xmr/bin/xmr.phar' -fi - -if [ "$XMR_DEV_MODE" == "true" ] -then - # Write config.json - echo '{' > /opt/xmr/config.json - echo ' "listenOn": "tcp://'$ip':50001",' >> /opt/xmr/config.json - echo ' "pubOn": ["tcp://'$ip':9505"],' >> /opt/xmr/config.json - echo ' "queuePoll": '$XMR_QUEUE_POLL',' >> /opt/xmr/config.json - echo ' "queueSize": '$XMR_QUEUE_SIZE',' >> /opt/xmr/config.json - echo ' "debug": '$XMR_DEBUG',' >> /opt/xmr/config.json - echo ' "ipv6RespSupport": '$XMR_IPV6RESPSUPPORT',' >> /opt/xmr/config.json - echo ' "ipv6PubSupport": '$XMR_IPV6PUBSUPPORT >> /opt/xmr/config.json - echo '}' >> /opt/xmr/config.json - - /bin/su -s /bin/bash nobody -c 'php /opt/xmr/index.php' -fi \ No newline at end of file +/usr/bin/php7 /opt/xmr/xmr.phar \ No newline at end of file diff --git a/tests/cmsSend.php b/tests/cmsSend.php index d0d2465..4974b9d 100644 --- a/tests/cmsSend.php +++ b/tests/cmsSend.php @@ -5,7 +5,7 @@ * (cmsSend.php) * * This is a CMS send MOCK - * execute with: docker exec -it xiboxmr_xmr_1 bash -c "cd /opt/xmr/tests; php cmsSend.php 1234" + * execute with: docker exec -it xiboxmr_xmr_1 sh -c "cd /opt/xmr/tests; php cmsSend.php 1234" * */ require '../vendor/autoload.php'; diff --git a/tests/playerSub.php b/tests/playerSub.php index 3b6a93d..8fe426a 100644 --- a/tests/playerSub.php +++ b/tests/playerSub.php @@ -5,7 +5,7 @@ * (playerSub.php) * * This is a player subscription mock file. - * docker exec -it xiboxmr_xmr_1 bash -c "cd /opt/xmr/tests; php playerSub.php 1234" + * docker exec -it xiboxmr_xmr_1 sh -c "cd /opt/xmr/tests; php playerSub.php 1234" * */ require '../vendor/autoload.php'; From c8736949de0d8955d3d86eaa318f199a84f1e703 Mon Sep 17 00:00:00 2001 From: Dan Garner Date: Fri, 5 Jan 2018 14:55:53 +0000 Subject: [PATCH 6/8] Update readme and ports in docker-compose. xibosignage/xibo#1368 --- README.md | 101 +++++++++++++++++++++++++++++++++++++-------- docker-compose.yml | 4 -- 2 files changed, 83 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index ba378a4..8fdaec4 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,97 @@ # Introduction Xibo - Digital Signage - http://www.xibo.org.uk -Copyright (C) 2006-2017 Spring Signage Ltd and Contributors. +Copyright (C) 2006-2018 Spring Signage Ltd and Contributors. This is the Xibo Message Relay (XMR) repository. -XMR is a php application built on ReactPHP which acts as a ZeroMQ message exchange between the Xibo CMS and connected -Xibo Players. It doesn't do anything beyond forward messages from the CMS to a pub/sub socket. +XMR is a php application built on ReactPHP which acts as a ZeroMQ message exchange between the Xibo CMS and connected Xibo Players. It doesn't do anything beyond forward messages from the CMS to a pub/sub socket. + +It is packaged into a PHAR file which is included in the [Xibo CMS](https://github.com/xibosignage/xibo-cms) release files. + +**If you are here for anything other than software development purposes, it is unlikely you are in the right place. XMR is shipped with the Xibo CMS installation and you would usually install it from there.** + -It is packaged into a PHAR file which is included in the [Xibo CMS](https://github.com/xibosignage/xibo-cms) release -files. ## Installation -The install, use composer: +XMR can be run using Docker and Compose, for example: + +```yaml +version: "3" + +services: + xmr: + image: xibosignage/xibo-xmr:latest + ports: + - "9505:9505" + - "50001:50001" +``` + + + +You may also build this library from source code: + +1. Clone this repository +2. Run `./build.sh` +3. Run `docker-compose up --build` + + +If you want to build for production which will only include the PHAR file, switch to a `Dockerfile`: + +``` yaml +version: "3" + +services: + xmr: + build: + context: . + dockerfile: Dockerfile + + ports: + - "9505:9505" + - "50001:50001" ``` + + + + + +You may also reference this code in your own projects via Composer: + +```bash composer require xibosignage/xibo-xmr ``` + + +### Ports + +XMR requires a listen address and a publish address and therefore needs 2 ports. The listen address is used for communication with the CMS (incoming comms) and the publish address is used for outgoing messages. + +When running in Docker, you will want to expose these ports to your machine OR connect your container to a Docker network which will facilitate communication with these ports. + +An example ports directive would be: + +``` yaml +ports: + - "9505:9505" #Publish + - "50001:50001" #Listen +``` + + + + + ## Licence -Xibo is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -any later version. - -Xibo is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with Xibo. If not, see . \ No newline at end of file + +Xibo is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. + +Xibo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License along with Xibo. If not, see . + + + +#### 3rd Party + +We use BOX to package the PHAR file - see https://github.com/box-project/box2 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index b9e7ba8..db2dd9e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,9 +6,5 @@ services: context: . dockerfile: Dockerfile-tests - ports: - - "9506:9505" - - "50001:50001" - environment: XMR_DEBUG: "true" \ No newline at end of file From f562cd7564c2e9b4374bf892025e16920fc5c4e2 Mon Sep 17 00:00:00 2001 From: Dan Garner Date: Fri, 5 Jan 2018 15:43:48 +0000 Subject: [PATCH 7/8] Switch to using non-PHAR method in container. xibosignage/xibo#1368 --- Dockerfile | 4 ++-- Dockerfile-tests | 23 ----------------------- README.md | 20 -------------------- docker-compose.yml | 5 +---- entrypoint.sh | 2 +- 5 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 Dockerfile-tests diff --git a/Dockerfile b/Dockerfile index f78fb50..a4b0342 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,12 +7,12 @@ ENV XMR_QUEUE_SIZE 10 ENV XMR_IPV6RESPSUPPORT false ENV XMR_IPV6PUBSUPPORT false -RUN apk update && apk upgrade && apk add tar php7 curl php7-zmq php7-phar php7-json && rm -rf /var/cache/apk/* +RUN apk update && apk upgrade && apk add tar php7 curl php7-zmq php7-phar php7-json php7-openssl && rm -rf /var/cache/apk/* EXPOSE 9505 50001 COPY ./entrypoint.sh /entrypoint.sh -COPY ./bin/xmr.phar /opt/xmr/xmr.phar +COPY . /opt/xmr RUN chown -R nobody /opt/xmr && chmod 755 /entrypoint.sh diff --git a/Dockerfile-tests b/Dockerfile-tests deleted file mode 100644 index 0f1811d..0000000 --- a/Dockerfile-tests +++ /dev/null @@ -1,23 +0,0 @@ -FROM alpine:3.6 -MAINTAINER Spring Signage Ltd - -ENV XMR_DEBUG false -ENV XMR_QUEUE_POLL 5 -ENV XMR_QUEUE_SIZE 10 -ENV XMR_IPV6RESPSUPPORT false -ENV XMR_IPV6PUBSUPPORT false - -RUN apk update && apk upgrade && apk add tar php7 curl php7-zmq php7-phar php7-json php7-openssl && rm -rf /var/cache/apk/* - -EXPOSE 9505 50001 - -COPY ./entrypoint.sh /entrypoint.sh -COPY ./bin/xmr.phar /opt/xmr/xmr.phar -COPY . /opt/xmr - -RUN chown -R nobody /opt/xmr && chmod 755 /entrypoint.sh - -# Start XMR -USER nobody - -CMD ["/entrypoint.sh"] \ No newline at end of file diff --git a/README.md b/README.md index 8fdaec4..bd23335 100644 --- a/README.md +++ b/README.md @@ -36,26 +36,6 @@ You may also build this library from source code: -If you want to build for production which will only include the PHAR file, switch to a `Dockerfile`: - -``` yaml -version: "3" - -services: - xmr: - build: - context: . - dockerfile: Dockerfile - - ports: - - "9505:9505" - - "50001:50001" -``` - - - - - You may also reference this code in your own projects via Composer: ```bash diff --git a/docker-compose.yml b/docker-compose.yml index db2dd9e..95a690f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,9 +2,6 @@ version: "3" services: xmr: - build: - context: . - dockerfile: Dockerfile-tests - + build: . environment: XMR_DEBUG: "true" \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index 49b122a..b306494 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -14,4 +14,4 @@ echo ' "ipv6RespSupport": '$XMR_IPV6RESPSUPPORT',' >> /opt/xmr/config.json echo ' "ipv6PubSupport": '$XMR_IPV6PUBSUPPORT >> /opt/xmr/config.json echo '}' >> /opt/xmr/config.json -/usr/bin/php7 /opt/xmr/xmr.phar \ No newline at end of file +/usr/bin/php7 /opt/xmr/index.php \ No newline at end of file From ea6390c664afc6b5bbc0de6469ba0d115a7b60f5 Mon Sep 17 00:00:00 2001 From: Dan Garner Date: Mon, 8 Jan 2018 09:50:31 +0000 Subject: [PATCH 8/8] Protect against messages without a QOS. xibosignage/xibo#1368 --- bin/xmr.phar | Bin 486661 -> 486835 bytes index.php | 8 +++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/bin/xmr.phar b/bin/xmr.phar index 6aa428d8a15dc1cb84886c22af78eeb0ef26a869..e01eaabf08e9ee93c95c43d7b3362ad8890a6736 100755 GIT binary patch delta 1734 zcmZ8iYfPI}7(Q+3_mxth_fnwr1KL7wf>}&eZj&(_a@i&umu{e)meO%4^aBH7b6zr? zj>N&2?GqW(A0rwUwPfnTaDq{zk<9GJ%nUe5+?E&=g~ZLcsPpuFyZx}q$&+)=bKduT zp7)%uhnFm8mo2f!B(mA^MxkEvxQe2`T0+P#^Di71G%lU+siXup|CVeAY>@5(oR;nd z@`#j>iL&;$g!iQtLY+(xivx7AYx*adpvf*0xKxFxo?%$==nRv>b}I;pC;LR!2vj|t zAG@WM3mYn*_~RKy!`5h!u|KH^7=8mG|I~iJRfs5kV%u|!iS-$gkt^Q~wG7LffqBS8 z$mfGo0l{kYiF0R}bhe2>rjuy_hFwXk{XlW*USXCYM$2{;BI_!H2298axlwxHPCTPv z)yYrHQPM;jl8&*>kaU$rBOXy;5fciWuPfSMe@AjV;7oEOAgkO9*rD75r8MaYIWza} zmqKxF!lMPo$Sx%8$xTT}OFR;O%>+jE+#f)d}kw(opX^X{hf` zS^(-_q9#Q)e`HDI#anVA9YtoVcLV9eJVF-3pH&MpX+H795TjiIa18=7F+ zYVZSoY``8FjhMXKxC_dyNg;&v3U!cd#fX|Lraf?I#1sHrG2x*HGBEd8#x_|0A)^}5 zZmxr1!&X9;zx(r7YU@Md>L}G7lVQ~t%})ZeI1?j`X5#$!Omwdy3(I{w3$KtO8|Q%p zp3mL~=dBjxKWjl*%NFF9=3vEd&iDMl$C2{8us z9KDh8_aDdmRywbO3q>5d(8FQOMGk8&$n`_4ct1ye>pprnmP(vG#pu+3V1xW|Jm|W- zDG|#dzSKdV`0MmZ$3Ft4d060N9ya}EUL6Rl%C7``C4U<2DZV z@@*A>L0c){Y1W3DndzwSbQse21Z9HTv%>bs;B z)*NP`-K`Zp-!e*J!JP!`uiPHMTkeMeH+dce?De4d_dK}1>Pd+AqPSi!nl0nm~-=9w$`Vw4|D}NelQy3c5ZLv!aTX|pg8#Ond TKe?vgklHWMKN<39Wqsv;m0CbN delta 1625 zcmX|BZERCj7(Q*+d;7KS_Iushwd>lhpKb{;MOR=BsEl<39gMB8=`d^x`+&_QTP8v@ z=!7P+-N1Fs5q~f>615E~*`{`c7>yHxQG?mUB?5_=q9subM8wngz3}7Y$vO8q@B2K@ zd+$B7Xg{=IPi>UQ3J!1L>m^TWC?;YOLVnAWD{V6bPM2=bO(@! zrG$*HYI}?SK)QyH%ZzaNJU!eq^^1(x*(!KvzCz&A3@aQ-GitU=K}fFIr?N(%8tMM% zExnw-sfh?bpJsGytqvKx^O}H>FcEUM?#K0fuPP$69%L+R#Egtm`Bu;}B;N+i0~SKg z4@|c64s%49J;M~RO$;*qOfxV%DysHF#mNW4?1PM+-Qz>n6$S$smlJY5`og_jN8VwO zAD^Y9aV?ULvfH5PGK)bxra%$n3fyNEt?+!avJEh;Yy@OgI{-UW+d)c`k&x4~?|s2n zmWmn8F=lp7jHgsBT2o^P*J$_7%f4woV~PmDF2>5;DF!`>9A3^IQ^K?k6u9|Hr9!xI zibn0=P;pYz0-b-=V9o0MX4p^UV{F&0gj8MKf9F9c$zkd@CPvqwMZfQA(ce97JLq4a zA@x>&Y#00DTk=@}nzV6Sf%K7!koo7%#rU)~A{-xNI5s94oadeZ5e^;3GoV9Jmvq=J zpvQ?B>BKs&rdsdY6N>gS26jY=)|T{Wt;+BeRGT#P0qTtdfQOC!IUF-J!M4Se0Q|&+ zGcud8d6#($$gNcqLVEZ(G+Q#GC%a`kTpG5t11?$c(!+(=d$e!^oc~l91N2zqP;AIS z$l?$G{7z$iL|9Hz?VCn3Y9XAz6g`KZ`KEhGLZaPBFeh3LEa*MVztig!>LV z@?W&0twlTXqa~>LLU4nL794(-X%Ohl}?dzNL{jLzQ&oC-sq?0jmv-FM3eg8Rp zXzAH2kV1tMQ|NYL&3PwkE-y_$t=v3^|L8h$zm`UrKFJukzi>c_9PST%ze23#6<+C} zpZFW}lg|AFqAnCT;liQ+?TUl3b!9bxua#|pCVu)y`f9f(&Hv{r8*@A1S($qc;4XI* z@RWNk;Iex)V9>J;u+Os|aK=*ysPNVUHhZf9C%ibeYhLW>FGv195vR+c&X^CcZT8i| zwKsj3%YwM~`tiKakLM{rer$>WTH6`G_Nl-sxStImKN?&M7Dwq!Cih;_^EbR!zAdO1 zLKhhoKNrjc_LspB;H}`JfGa{P0eeDd{{0Z1FNZ|)VKmnh#;``iC7c)knu#2~o|LIy z&V*mhge7!I>5|cvN0*!~=4>X+)d^oI diff --git a/index.php b/index.php index d827504..676975c 100644 --- a/index.php +++ b/index.php @@ -113,8 +113,14 @@ function exception_error_handler($severity, $message, $file, $line) { // Respond to this message $responder->send(true); + // Make sure QOS is set + if (!isset($msg->qos)) { + // Default to highest priority for messages missing a QOS + $msg->qos = 10; + } + // Decide whether we should queue the message or send it immediately. - if (isset($msg->qos) && $msg->qos != 10) { + if ($msg->qos != 10) { // Queue for the periodic poll to send $log->debug('Queuing'); $messageQueue[] = $msg;