ScalaでJavaScriptからプロゞェクトを曞き盎した方法



歩けない クロヌルしおいるからです。

-偉倧な名蚀



私はい぀も䞻にこんにちはず蚀うように教えられおきたので、こんにちは。 今日は、人生の特定の期間に経隓した創造的なそしおそうではない苊痛、苊しみ、痛みに぀いお話したす。これをプロゞェクトず呌びたす。 最初はJavaScriptnode.jsにありたしたが、珟圚はScalaPlayにありたす。 私は芳察可胜な宇宙で最も䞻芳的な悪党の䞀人であるずすぐに蚀わなければならないので、尊敬される読者は非垞に曖昧に、いく぀かのタヌン、声明、およびそのような他のものを知芚できたす。 芁するに、私は譊告した。 そしお、もう1぀小さな芁望がありたす。すでに蚘事を読み始めおいる堎合は、急いでコメントを曞いおください。 読んで 私はパヌスニップではなく、真実を語っおいたす。 そしお、䞀般的に、私は䜕らかの圢で論争の的になっおいる問題のほずんどすべおを䜕らかの方法で説明したす。



プロロヌグ



しかし、たず第䞀に、私は少し䜙談をさせお、私が䜕をしたのか、そしおそれがどのくらい始たったのかを説明したす。

箄1幎半前、私は自分の技術倧孊で論文のトピックを遞択するこずに盎面したした。 もちろん、掗車甚の䞀般的なWebサむト、Coffeehouse Webサむトの新しいデザむンの別のコンセプト、たたは同様の䜕かで自分を正圓化するこずができたすちなみに、これらは実際の卒業プロゞェクトであり、緊匵したすが、省略したす。 しかし、私たちは頑固であり、この分野の専門家ですらありたす 簡単な方法ず䜕ずか䜕ずかを探しおいるわけではありたせん。

その時たでに、私はすでに玄3幎の実務経隓があり、6〜7幎はプログラミング、特にWebで燃え尜きおいたした。 したがっお、私の前に実装に関する質問はありたせんでした。 残りのトピック、぀たり同じプロゞェクトがありたした。 地元の人は苊しみを通しおの開発に関する楜しい蚘事を知っおいるべきです。

ですから、その時、䞀緒に仕事をしたり、仲間ず次のYPを勉匷したりしお、本圓に苊しみたした。 pastebinに䌌たツヌルが必芁でした。 送信枈み-リンクのコピヌ-共有ずしおは自明ですが、それでもGoogle Docsチップを䜿甚しおいたす。぀たり、同時にコヌドを線集しおいたす。 同意する-誰かが暪枠にカヌ゜ルを眮き、2回のキヌストロヌクでそれを修正する方法を芋るだけでクヌルです。 たあ、毎回同じコヌドを耇補しおリンクを倉曎するよりも高速です。 痛み

そしお、私はこれらのサヌビスを探しおこれらのあなたのむンタヌネットを駆け巡りたした、そしお...は芋぀かりたせんでした。 もちろん、Eclipse、Sublimeなどのほかにプラグむンを知っおおり、スタンドアロン゜リュヌション党䜓に぀いおも知っおいたす。 しかし、ペヌストビンほど単玔なものは芋぀かりたせんでした。 したがっお、私のプロゞェクトはカりントダりンを開始したした。



第1章JavaScript



プロロヌグから、䜜業の短い声明、必芁なサヌビスずは䜕か、そしおそれをどのように実行すべきかをすでに圢成しおいる可胜性がありたす。

倧たかに蚀えば、ナヌザヌチャットルヌムがいく぀かありたす。チャットの代わりに、みんながじっず芋おいるコヌドがありたす。 どうやっお 芁するに-私はフラッシュが奜きではない、私はりェブ゜ケットが欲しい。

圓時、私はPHPに固執しおいたしたが、その䞊でWebSocketサヌビスを䜜成したした。党二重接続は、無限に続く可胜性があり、地獄ぞの盎接の道です。 そのため、WSサヌビスずしおのnode.jsに泚目し、静的を生成しおパフを䞎えたした。 そしお、あなたは䜕を知っおいたすか それはすごかった。 数日でプロトタむプを投げたした。 すべおがうたくいきたした 、そしおそれは蚀葉で衚せない気持ちでした。 たるで匊理論を完党に実珟したようです。 たたは、ブラックホヌル内の情報が消える堎所を掚枬したした。 たあ、あなたは私を理解しおいたすか そしお、WebSocketをプロキシできるnginx'aリリヌスをリリヌスしたした。

リャポタ
// ,        .    . var sockjs_im = sockjs.createServer(sockjs_opts); sockjs_im.on('connection', function(c) { //     sender.setValidTimeout(c); //   c.on('data', function(message) { sender.process(message,c); }); c.on('close',function() { connection.removeConnection(c); }) }); var server = http.createServer(); server.addListener('upgrade', function(req,res){ res.end(); }); sockjs_im.installHandlers(server, { prefix: config.get("path") }); exports.startWSServer = function() { server.listen(2410, '0.0.0.0',function() { console.log(' [*] Listening WS on 0.0.0.0:2410' ); }); }
      
      







しかし、ビゞネスに戻りたす。 私はこのハンマヌを぀かんで呚りのすべおを叩き始め、そこで圌らにすでに理解させたした-誰が釘で誰がラクダなのか。 圌は最も流行に敏感なテクノロゞヌを採甚したしたWS接続のクラむアントサヌバヌずしおのSockJS、デヌタベヌスずしおのMongoDB、クラむアントの゚ディタヌずしおのAce Editor、それらを盲目にし、バむンディング、ロゞックの蚘述を開始したした。

それから私は小さなメモをしたす-プロゞェクトは卒業匏でしたので、私は迅速か぀安䟡に、そしおすぐにすべおをしなければなりたせんでしたが、私は仕事をしお䜕かを枡す必芁がありたした。


1か月埌、別の゚ネルギヌの猶ができた埌、私はスクリヌンから赀い目を匕き裂き、すぐに死ぬほうがよいモンスタヌ、クリヌチャヌが生たれたこずに気付きたした。 いいえ、機胜し、倱敗するこずなく、 ほずんどすべおの機胜が準備できたした。 しかし、その仕組みはすばらしかった。 私は臎呜的な間違いを犯し、プロトタむプを曞き盎したせんでした。 䜜り䞊げたした。 コヌドは耇雑で冗長になりたした。

その瞬間から、プロゞェクトの仕事は拷問に倉わりたした。 新しい機胜たたは機胜を远加するには、倚くの劎力が必芁でした。 Sisyphusのように感じたした。石だけが正方圢でもありたした。 悲惚。

論理的な質問は-䜕に぀いお話しおいるのですか 以䞋に短いリストを瀺したす。



そしお、7番目のサヌクルのベルトを守っお蚀うミノタりロスが来たす

- ねえ、男。 たあ、あなたは自分でばかです。 圌は悪魔を曞いた、あなたはあなたの足を折る、圌自身は認めた。 あなたの問題は䜕ですか

そしお、あなたは私が答えるのを知っおいたすか これはすべおJavaScriptです。 ぀たり、誀解しないでください。IQ>>> infinityで私がずおもキュヌトでふわふわしおいるずいう意味ではありたせん。 ぀たり、蚀語自䜓は 、そうではなく、このように曞くこずを奚励しおいたす。 ささやくような䞀皮の蛇

- さあ、匕数で3番目のコヌルバックをここですぐに固執しおください。

そしお、私の目の前のこのような長い赀い舌。

それはすべおこのようなものに芋えたした
 /** *  .   -     ... */ var loadSession = function(sessid, callback) { if(typeof sessid != 'string') return; var sess = sessions.getSession(sessid); sess.setLoadCallback(callback); } ... /** *  ,  ,   ,     . *   -,     . */ loadSession(msgObj["sessid"], function(sess) { var r = rooms.getRoom(msgObj["room"]); r.setLoadCallback(function() { r.addUser(connection, sess, function(newUser) { if(newUser!==false) { var outMsg = { action: "newUser", data: newUser } r.broadcast(connection, outMsg); r.write(connection,{ action: "join" }); }else{ error(connection,{ error:true, errsmg: "something went wrong" }) } }); }); }); ...
      
      







おそらくこれはすべおの゚ネルギヌであり、ヘビのいるミノタりロスは私に来たせんでしたクロヌルされたしたが、それは䜕が起こったのか刀明したした。 卒業蚌曞は合栌したしたが、生き物ず呌ぶこずができれば、生き物は生きたたたでした。

この怪物をリファクタリングしようずか、すべおをコヌヒヌスクリプトに曞き盎そうずするいく぀かの詊みの埌、私はこの悪魔をより良い時たで捚おお、ペヌロッパ䞭を走りに行きたした。 ええ、私はずおも深く萜ちお、過去の悪倢から遠く離れお走りたした



第2章Scala



6か月が経過したした。 獣はすべお存圚しおいたしたが、私はそれを終わらせ、すでに生産䞭にそれをリリヌスするこずを望みたせんでした。 JavaScriptコヌドを開くず、呌び出し音で嘔吐するために䜿甚された金属補の掗面噚を緊急に実行する必芁がありたした。

そしお、むンタヌネットで迷子になっお、Play Frameworkサむトに行き着きたした。 サむトで私を惹き぀け、遅らせたものを芚えおいたせんが、それは重芁ですか その結果、1日埌にフレヌムワヌクを掘り䞋げ、最初のアプリケヌションを䜜成し、coursera.orgのScalaコヌスに登録したした。

特に最初は簡単だったずは蚀えたせん。 もちろん、パむ゜ンやパフはもっずシンプルですが、Qt / C ++ずJavaのバックグラりンドを持っおいるので、少なくずも芁点に぀いおは、めん棒をかなり玠早く芋぀けたした。 暗黙の倉換ずパラメヌタヌを味わうために、co / counter / invarianceなどのようなものは、Googleスキルを掻甚しおさたざたな䟋ずドキュメントを怜玢し、ボンネットのどこかで起こっおいるこずの党䜓像を把握する必芁がありたした。 それでも、しばらくの間、私は銬鹿げたブヌツのように感じたしたが、これは正垞であるずいう意芋がありたす。

そしお今、少しぬいぐるみを持っお、私はPlayがwebsocketでそれをどのように行えるかを芋るこずにしたした。 そしお、ここで私は氷氎の济槜のように泚がれたした。 最初の反応はシンプルでした-WTF ??? キュヌトで手頃な䟡栌の゜リュヌションはどこに行きたしたかほが䜎レベルのIteratee / Enumerateeを備えたこの機胜的なハヌドコアずは䜕ですか はい、JavaScriptの倱敗ずは䜕の関係もありたせん。 push



ずonMessage



返しおください

チャンネルじゃなくお
 def index = WebSocket.using[String] { request => // Just consume and ignore the input val in = Iteratee.consume[String]() // Send a single 'Hello!' message and close val out = Enumerator("Hello!").andThen(Enumerator.eof) (in, out) }
      
      







しかし、あたりにも単玔な゜リュヌションの苊い経隓を​​教えられお、私はあきらめず、再び取り䞊げるこずに決めたした...いいえ、ハンマヌではありたせん。 Google。 その結果、快適なアプロヌチが発芋されたした

Concurrent.unicast
 val promiseIn = Promise[Iteratee[String, Unit]]() val out = Concurrent.unicast[String]( onStart = onStart(promiseIn, r, userSession), onError = onError ) (Iteratee flatten (promiseIn.future), out) ... private def onStart(promiseIn: Promise[Iteratee[String, Unit]], ...): (Channel[String] => Unit) = { ... (ch: Channel[String]) => { val channel = new ChannelContainer(ch) for (optUserConnection <- isConnectedF(r, channel)) yield { optUserConnection match { case Some(userConnection) => { val in = Iteratee.foreach[String] { MessageController onMessage (r, userConnection, channel) //bind handler for room and this connection } map { MessageController onDisconnect (r, userConnection, channel) //handler for disconnect } promiseIn success in //success promise and fill it with iteratee } case None => channel eofAndEnd //in case of some troubles with new user creation - close connection } } } }
      
      







はい、同意したす。 ただあたりキュヌトで面倒ではないように芋えたすが、メッセヌゞング甚に䜜成された暙準チャネルを䜿甚しお、これらのチャネルをラッパヌにプッシュし、メッセヌゞずずもに俳優に転送するこずができたす。

Scalaのアクタヌ。 私の心のトルコの喜び。 最高のパラダむム゚ノァ たあ、たたは確かに私の目的に必芁なもの。 郚屋は俳優であり、郚屋の管理者は俳優です。 そしお、顧客でさえ俳優です。 論理的にナヌザヌ間のメッセヌゞングのむデオロギヌに流れ蟌みたす。 ずころで、Playの開発者もこのトピックを聞いおおり、最近リリヌスされたバヌゞョン2.3

WebSocket接続もアクタヌになりたした
 import play.api.mvc._ import play.api.Play.current def socket = WebSocket.acceptWithActor[String, String] { request => out => MyWebSocketActor.props(out) }
      
      





 import akka.actor._ object MyWebSocketActor { def props(out: ActorRef) = Props(new MyWebSocketActor(out)) } class MyWebSocketActor(out: ActorRef) extends Actor { def receive = { case msg: String => out ! ("I received your message: " + msg) }
      
      







そしお、宇宙があなたを聞いおいるのは玠晎らしいこずです。 私からの信号は、虹のような蝶の惑星で、ここから光幎の間にある衚面からただ反射し、戻っおきたした。 クォンタムは混乱し、アリスずボブはお互いを芋぀けたした。 そしお、私は平和を芋぀けたした。

なんで ほずんどの堎合、Scalaは䜕か間違ったこずをした堎合、あなたをたわごずのように芋おいるだけです。 圌女はあなたに蚀っおくれたす

-ガむ、私はモナドの圢でネむティブのFutureサポヌトを提䟛し、JSONメッセヌゞを必芁なケヌスクラスのむンスタンスにキャストし、倚くの特性を継承する機胜を提䟛したす、私はあなたを確認したす それを正しく行うか、ミノタりロスで地獄に戻っおください。

厳栌だが公正な仲間。 ひげを生やしたハむれンベルクプログラミング。 うん、Scala、biaaatch そしお、マヌティン・オヌデルスキヌ自身があなたを埌ろから芋぀めおいたす。



゚ピロヌグ



それでは、このような混waterずした意識氎の流れの埌に䜕が蚀えるのか、結論は䜕ですか

最初のもの 。 蚀語を比范したせん。 パスタを保存したす。 ScalaずJavaScriptを比范する-これは、ラむオンずおばあちゃんのケヌキを比范する方法です。 はい、おばあちゃんのパむを食べるこずができたす。 しかし、ラむオンはありそうもない。 しかし、ラむオンはあなたを食べるこずができたす。 これらは異なるタスクのための異なる蚀語です。 Scalaフロント゚ンドは誰が䜜成したすか

二番目 。 特定の問題を解決するために䜿甚される蚀語ずプラットフォヌムを提䟛する機胜、たたはむしろアプロヌチを比范したす。 玳士ですが、コヌルバックは適合したせん これはク゜評決です。

10個のFutureから1行を䜜成しお、その実行を埅぀こずができたす。 Futureがモナドであるずいう理由だけで、蚀語の粟神では、すべおがシンプルで自然に芋えたす。 コヌルバックに぀いおは、終了した関数の数をカりントするか、本栌的なDeferred / Promiseになるラッパヌを䜜成する必芁がありたす。 はい、はい、JavaScript甚のそのようなラむブラリの存圚に぀いお知っおいたす。 しかし、これらは同じコヌルバックの単なる肥倧化したラッパヌです。 閉じた地獄円。

3番目 。 JavaScriptを今よりもうたく曞けたすか 間違いなく。 芋た目も動䜜も簡単だったかもしれたせん。 1぀のタむプの問題を解決する経隓は経隓であり、飲むこずはできたせん。 Scalaよりもうたくいくでしょうか 事実ではありたせん。 はい、Scalaでは、いく぀かの堎所でさらに倚くのコヌドを蚘述する必芁がありたすが、気を぀けおください JSONからオブゞェクトを取埗する1぀のメ゜ッドに察しお䜕癟ものテストを蚘述する必芁はありたせん。すべおが意図したずおりに動䜜するこずを確認したす。 ある皮のスクリプトキディは、配列の文字列、数倀の配列などを眮き換えたせんでした。 私にずっおは、蚀語、プラットフォヌム、コンパむラヌによっお行われたす。

4番目 。 Scalaは耇雑 、 Scalaは耇雑 、 Scalaは耇雑です。 数千人。 䜕ずか䜕ずか。 䜕が難しいか知っおいたすか このコンテキストず、javascript忍者の神経節を絶えず悩たせおいる他の䜕癟もの偎面に留意しおください。 真剣に、JSeで倚数のロゞックを持぀倧芏暡なプロゞェクトを曞くには、Scalaよりもはるかに倧きな専門家である必芁がありたす。 お尻で感じたした。 毎日この䞍平等な戊いに参加しおいる人たちを尊重しおください。 あなたはクヌルで、冗談ではありたせん。 JavaScriptは簡単ではありたせん。

しかし、私自身のために、私は苊したないこずに決めたした。 なんで



All Articles