📜 ⬆️ ⬇️

How the site can send events ...

Once upon a time (I don’t remember when, but long ago) I got together and launched a website for myself. At first it was used simply as a warehouse of what needs to be conveyed to someone. Then, quite by chance, free time was formed and it turned out to fill the site with something meaningful and (hopefully) useful. And I really wanted to be aware of the events taking place on the site. The simplest solution is to send letters, which was done. However, after some time, there was a desire to get rid of letters from the site as the flow of service mail during the day exceeds reasonable limits.

And then the thought occurred that using mail as a transport for delivering site events is simply one of the most common approaches, but there are also transports that allow you to not only send messages almost instantly, but also monitor the recipient’s status and guarantee the delivery of the event. One such transport is jabber.

A bit of reasoning before rushing into implementation.


So, at the moment the server sent me letters at any time:
  1. Suggestions / comments that can be sent from the site
  2. Information on downloading files from the site
  3. Regularly small stats

I didn’t have to deliver all of these events at any time: I need information about downloading files from the site as the fact that “right now someone is taking a file from the site”, rather than raking several emails in the morning after receiving the mail. It would be more interesting to get statistics on demand (yes, you can just make a page, but such pages usually turn into monsters, but you need to see something like summary). Thus, sending events should be like this:
  1. Suggestions / comments that can be sent from the site - always sent
  2. Information about downloading files from the site - is sent only when I am on-line
  3. Regularly small statistics - when I wanted to look at it

By the way, my IM client starts up automatically and much earlier than the email client i. I will see the site events faster.

Preparatory work.


For a start, I started a jabber ID under which my site will run. I did not bother with the support of the authorization request site, I did all the necessary actions to add contacts and authorization manually, since this is just an experiment. In the future, you need to bind registered users to the contact list of the server.
The second most important matter was the choice of a library for working with jabber protocol. The network found a sufficient number of projects for .NET, but the final choice of a particular library, I have not done yet. still keep comparing them.
')

We make from the site jabber client.


Everything is ready for implementation and the first code that was written, just logged in to the jabber server and appeared in my online contacts at the start of the site. The first problem that threatened to stop the experiment: for some reason, some libraries believe that they are simply obliged to ask the user for confirmation. Naturally, the site could not answer them, and did not give a simple window. After a simple replacement of the library for working with the protocol, I finally saw the long-awaited inscription "[Server] On-Line" Then I got excited - I encountered this problem in a completely different library - the library for working with SVN, which I also attached to the site.

We start to send events.


Actually, the whole development consisted in writing the void SendMessage method (Jid to, bool alwayssend, string format, params object [] args) and placing calls to this method. I also wrote a small method for auto answer:
protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  1. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  2. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  3. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  4. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  5. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  6. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  7. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  8. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  9. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  10. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  11. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  12. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  13. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  14. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  15. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  16. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  17. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  18. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  19. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  20. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  21. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  22. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  23. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  24. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  25. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
  26. protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .
protected void processMessage(Jid jid, string text) { string cmd = new Regex( "\\s+" , RegexOptions.ECMAScript).Replace(text, " " ).ToLower(); switch (cmd) { case "?" : SendMessage(jid, false , ":\n" + " ? - \n" + "? - IP \n" + "? - \n" + " ? - ." ); break ; case " ?" : SendMessage(jid, false , Collector.GetSummary()); break ; case "?" : SendMessage(jid, false , Collector.GetIPs()); break ; case "?" : SendMessage(jid, false , Collector.GetPages()); break ; case " ?" : SendMessage(jid, false , Collector.GetServers()); break ; } } * This source code was highlighted with Source Code Highlighter .

Everything, now I see, when my site works, sends me the necessary events and answers questions. This is what the chat window with my site looks like:
image
Actually write an answering machine is not difficult.

Results


Using the jabber protocol as a transport for delivering site events is convenient and easy. The advantage is immediately visible - all events can be divided into several types and tied to the presence of the user (in this case, me) on communications and (if necessary) on my status (do not disturb, busy, etc.):
The number of “like” necessary letters has been reduced, which in 99% of cases are deleted without reading.
In general, it turned out that the potential of such a solution is quite high. For example, you can go further - drastically change the registration process: ask only jabber ID, send an authorization request, pull out the initial data and send a password, but for now the low prevalence of using the protocol stops.
The implementation of the test mechanism on the server fit into 134 lines of code, if anyone is interested, I can lay out, but this code is almost completely taken from the examples that came with the library. While I like the results, the experiment continues. Ahead - load testing, tight work with a list of contacts through the site and a lot of ideas.

Addition: about components for working with jabber

The first worthy project is Jabber .NET : since mail and jabber for my domain work through Google Apps, the main criterion is normal work with google, the connection work went smoothly. There are some flaws, but the basic functions are provided quite well. What did not suit me:
  1. Inheritance of objects from System.ComponentModel.Component
  2. Multiple dll
  3. The structure of the project is completely incomprehensible to me, the projects are too mixed


The second project is agsxmpp : I am currently using it, but most likely I will have to give it up because of the license. Again, google works fine, the library is more serious than the first.

Both considered libraries contain components for Windows.Forms, but firstly they cannot be looked at without a shudder, and secondly they are unnecessary for me on the server.

Everything else that I could find was swept away already at the stage of studying sites. However, there are some good JScript projects, maybe one of them can simply be ported to C #.

Source: https://habr.com/ru/post/43844/


All Articles