{"id":714,"date":"2017-06-05T09:29:41","date_gmt":"2017-06-05T09:29:41","guid":{"rendered":"http:\/\/smartfoxserver.com\/blog\/?p=714"},"modified":"2017-06-05T09:38:53","modified_gmt":"2017-06-05T09:38:53","slug":"kotlin-and-smartfoxserver-2x-part-2","status":"publish","type":"post","link":"https:\/\/smartfoxserver.com\/blog\/kotlin-and-smartfoxserver-2x-part-2\/","title":{"rendered":"Kotlin and SmartFoxServer 2X, part 2"},"content":{"rendered":"<p>In the <a title=\"SFS2X and Kotlin, Part one\" href=\"http:\/\/smartfoxserver.com\/blog\/kotlin-and-smartfoxserver-2x\/\">last article<\/a> we&#8217;ve introduced\u00a0Kotlin, a modern language for the JVM and now a Google approved\u00a0language for Android development. We have shown how simple it is to use Kotlin on the server side to develop SmartFoxServer Extensions.<\/p>\n<p>Now it&#8217;s the time to see how to integrate the SFS2X Java API with Kotlin to build a client application.<!--more--><\/p>\n<h2>\u00bb Setting up the project<\/h2>\n<p>In the previous episode we have talked about\u00a0<a title=\"Download IntelliJ \" href=\"https:\/\/www.jetbrains.com\/idea\/download\/#section=mac\" target=\"_blank\" rel=\"noopener noreferrer\"> Jetbrain\u2019s IntelliJ<\/a>, a multi-language IDE that is also provided\u00a0as a\u00a0\u201cCommunity Edition\u201d, free of charge. This is the easiest way to get started, as the IDE supports Java and Kotlin out of the box without additional downloads.<\/p>\n<p>We also need\u00a0a copy of the <a title=\"SFS2X Java API\" href=\"http:\/\/smartfoxserver.com\/download\/sfs2x#p=client\" target=\"_blank\" rel=\"noopener noreferrer\">latest SmartFoxServer client API for Java<\/a>, which we will unzip in a folder of our choice. Once IntelliJ is installed we can go ahead and create a new project, from <strong>File<\/strong> &gt; <strong>New<\/strong> &gt; <strong>Project<\/strong>, choose <strong>Kotlin (Java)<\/strong> as the project type and continue\u00a0with the procedure.<\/p>\n<p>Next,\u00a0we need to add the SFS2X client API to our project: right-click on the project&#8217;s name, select <strong>Open Module\u00a0Settings<\/strong>, and select the <strong>Libraries<\/strong>\u00a0item from the left-side column. From the second column click the <strong>plus (+) sign<\/strong> and navigate to the folder where you have previously \u00a0unzipped the API.<\/p>\n<p><a href=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2017\/05\/kot-client-step1.png\"><img loading=\"lazy\" class=\" size-full wp-image-715 aligncenter\" src=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2017\/05\/kot-client-step1.png\" alt=\"kot-client-step1\" width=\"1023\" height=\"261\" srcset=\"https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2017\/05\/kot-client-step1.png 1023w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2017\/05\/kot-client-step1-300x77.png 300w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2017\/05\/kot-client-step1-624x159.png 624w\" sizes=\"(max-width: 1023px) 100vw, 1023px\" \/><\/a><\/p>\n<h2>\u00bb\u00a0A basic Kotlin\/SFS2X client<\/h2>\n<p>We can now write our client code:<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\nimport sfs2x.client.SmartFox\r\nimport sfs2x.client.core.BaseEvent\r\nimport sfs2x.client.core.IEventListener\r\nimport sfs2x.client.core.SFSEvent\r\nimport sfs2x.client.requests.LoginRequest\r\nimport sfs2x.client.util.ConfigData\r\n\r\nclass SFSEventListener : IEventListener\r\n{\r\n    override fun dispatch(evt: BaseEvent?)\r\n    {\r\n        when (evt?.type)\r\n        {\r\n            SFSEvent.CONNECTION -&gt; onConnection(evt)\r\n            SFSEvent.CONNECTION_LOST -&gt; println(&quot;Connection lost&quot;)\r\n            SFSEvent.LOGIN -&gt; println(&quot;Logged in as: ${sfs.mySelf.name}&quot;)\r\n            SFSEvent.LOGIN_ERROR -&gt;\r\n            {\r\n                val errorMsg = evt.arguments.get(&quot;errorMessage&quot;);\r\n                println(&quot;Login failed: ${errorMsg}&quot;)\r\n            }\r\n        }\r\n    }\r\n\r\n    fun onConnection(evt:BaseEvent)\r\n    {\r\n        val success = evt.arguments.get(&quot;success&quot;) as Boolean\r\n\r\n        if (success)\r\n        {\r\n            println(&quot;Connected to server...&quot;)\r\n            sfs.send(LoginRequest(&quot;&quot;, &quot;&quot;, cfg.zone))\r\n        }\r\n\r\n        else println(&quot;Connection failed!&quot;)\r\n    }\r\n}\r\n\r\nval sfs = SmartFox()\r\nval cfg = ConfigData()\r\nval listener = SFSEventListener()\r\n\r\nfun main(args: Array&lt;String&gt;)\r\n{\r\n    println(&quot;SFS2X API Version: ${sfs.version}&quot;)\r\n\r\n    cfg.host = &quot;127.0.0.1&quot;\r\n    cfg.port = 9933\r\n    cfg.zone = &quot;BasicExamples&quot;\r\n\r\n    sfs.setClientDetails(&quot;Kotlin&quot;, &quot;&quot;)\r\n    sfs.addEventListener(SFSEvent.CONNECTION, listener)\r\n    sfs.addEventListener(SFSEvent.CONNECTION_LOST, listener)\r\n    sfs.addEventListener(SFSEvent.LOGIN, listener)\r\n    sfs.addEventListener(SFSEvent.LOGIN_ERROR, listener)\r\n\r\n    \/\/ Start connection\r\n    sfs.connect(cfg)\r\n}\r\n<\/pre>\n<p>Before we start with the <strong>main()<\/strong> method notice a few stark\u00a0differences with Java. We don&#8217;t have to enclose our main() method and variables in a class.\u00a0This approach resembles\u00a0more dynamic languages such as Python or Javascript, at least on the surface.<\/p>\n<p>You can also notice that\u00a0variables can be declared in an apparently type-less fashion using the <strong>val<\/strong> or <strong>var\u00a0<\/strong>keywords. The former represents\u00a0an immutable value (equivalent to Java&#8217;s <strong>final <\/strong>modifier) while the latter is used for mutable values.<\/p>\n<p>We said\u00a0that this approach is &#8220;apparently type-less&#8221; because in reality it isn&#8217;t. Kotlin is a statically typed language that supports <a title=\"Type inference\" href=\"https:\/\/en.wikipedia.org\/wiki\/Type_inference\" target=\"_blank\" rel=\"noopener noreferrer\">type inference<\/a>, which means that the compiler will auto-detect what types are being used even without explicit declaration. In those rare exceptions where type detection is not possible an error will be generated.\u00a0In any case we can always be explicit with our type declarations using this syntax:<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">val sfs:SmartFox = SmartFox()<\/pre>\n<p>(Also notice how objects are instantiated without the use of the <strong>new<\/strong> keyword, as in Java)<\/p>\n<p>With this out of the way we can now go back to our <strong>main()<\/strong> method. The first line outputs the version of the API in use. Here we can see another interesting feature in Kotlin:\u00a0<a title=\"String templates in Kotlin\" href=\"https:\/\/kotlinlang.org\/docs\/reference\/basic-types.html#string-templates\" target=\"_blank\" rel=\"noopener noreferrer\">string templates<\/a>, which allows to write complex expressions directly in a string without the need for concatenation or placeholders.<\/p>\n<p>The rest of the code should be\u00a0straightforward: we set up the basic settings for the connection and add several event listeners, all pointing to the same instance of our <strong>SFSEventListener<\/strong> class. This in turn overrides the <strong>dispatch()<\/strong> method, just like in Java, and uses a\u00a0<a title=\"When expressions\" href=\"https:\/\/kotlinlang.org\/docs\/reference\/control-flow.html#when-expression\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>when <\/strong>block<\/a>\u00a0to dispatch different events to their handlers. You can think of this as the equivalent of the\u00a0<strong>switch<\/strong> statement in Java.<\/p>\n<p>Finally in the <strong>when<\/strong> block we have used a mix of lambdas and method references to show that both are supported, just like in Java 8 and most modern languages supporting the functional paradigm.<\/p>\n<p>In a nutshell, for those not entirely familiar with these concepts:<\/p>\n<ul>\n<li><strong>lambdas<\/strong>: are anonymous functions that can be passed &#8220;on the spot&#8221;, typically they contain just a few lines of code. For longer code you may want to use the next\u00a0type.<\/li>\n<li><strong>method references<\/strong>: these are references to methods declared somewhere else in the code, and can be passed around just like any other variable. These are\u00a0useful when the method contains more than just a few lines of code.<\/li>\n<\/ul>\n<h2>\u00bb Next steps and resources<\/h2>\n<p>To learn more about Kotlin and its capabilities we highly recommend several interesting resources:<\/p>\n<ul>\n<li><a title=\"Google I\/O 17 Intro to Kotlin\" href=\"https:\/\/www.youtube.com\/watch?v=X1RVYt2QKQE\" target=\"_blank\" rel=\"noopener noreferrer\">Google I\/O \u201917 Introduction to Kotlin<\/a> (YT video)<\/li>\n<li><a title=\"Official Kotlin website\" href=\"https:\/\/kotlinlang.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">Official Kotlin language website<\/a><\/li>\n<li><a title=\"Try Kotlin online\" href=\"https:\/\/try.kotlinlang.org\/#\/Examples\/Hello,%20world!\/Simplest%20version\/Simplest%20version.kt\" target=\"_blank\" rel=\"noopener noreferrer\">Try Kotlin online<\/a>\u00a0(try Kotlin without installing anything)<\/li>\n<li><a title=\"Kotlin reference\" href=\"https:\/\/kotlinlang.org\/docs\/reference\/\" target=\"_blank\" rel=\"noopener noreferrer\">The Kotlin reference<\/a> (also available as downloadable PDF)<\/li>\n<\/ul>\n<p>In the next installment we will put all we have learned so far to good use, by building a client and server example in Kotlin.<\/p>\n<p>Stay tuned.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last article we&#8217;ve introduced\u00a0Kotlin, a modern language for the JVM and now a Google approved\u00a0language for Android development. We have shown how simple it is to use Kotlin on the server side to develop SmartFoxServer Extensions. Now it&#8217;s the time to see how to integrate the SFS2X Java API with Kotlin to build [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/714"}],"collection":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/comments?post=714"}],"version-history":[{"count":16,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/714\/revisions"}],"predecessor-version":[{"id":734,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/714\/revisions\/734"}],"wp:attachment":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/media?parent=714"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/categories?post=714"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/tags?post=714"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}