前提・実現したいこと
ScalaとScalaFXを使用したソケット通信オセロプログラミングを作成しています。
ソケット通信自体はうまくいきましたが、通信後のオセロを盤面に描画する際に思った通りの動作をしなくて困っています。
発生している問題・エラーメッセージ
ソケット通信がサーバー・クライアント間で完了したのち、お互いにメッセージのやりとりをして、そのメッセージに沿って黒丸or白丸を描画する際に、即座に描画したいのですが、自分の盤面をクリックした際に、相手からの応答があってから相手の円と自分の円が同時に描画されます。これを即座に描画するようにしたいです。
該当のソースコード
Scala 2.12.7
OseloContoroller.scala
package gui import java.net.Socket import scalafx.Includes._ import scalafx.scene.input.MouseEvent import scalafx.scene.paint.Color._ import scalafx.scene.layout.GridPane import scalafxml.core.macros.sfxml import javafx.scene.shape.Circle import scalafx.scene.paint.Color import network._ import scalafx.scene.control.Button @sfxml class OseloController(val board: GridPane, val connecteButton: Button, val serverButton: Button){ val server: Server = new Server(8000, board) var client: Client = _ var flag: Boolean = _ //白黒の順番判定trueが黒、falseが白 var posX:Int = _ var posY:Int = _ serverButton.onMouseClicked = (_: MouseEvent) =>{ server.createServer flag = true } connecteButton.onMouseClicked = (_: MouseEvent) =>{ val sc: Socket = new Socket("127.0.0.1", 8000) client = new Client(sc, board) flag = false client.createClient() client.receiveMsg() } board.onMouseClicked = (e:MouseEvent) => { posX = (e.x / 53).asInstanceOf[Int] posY = (e.y / 53).asInstanceOf[Int] if(flag) { server.sendMsg(posX.toString + "," + posY.toString) server.receiveMsg() }else{ client.sendMsg(posX.toString + "," + posY.toString) client.receiveMsg() } } }
Server.scala
package network import java.io._ import java.net._ import javafx.scene.shape.Circle import scalafx.scene.layout.GridPane import scalafx.scene.paint.Color import scalafx.scene.paint.Color._ class Server(val port: Int, val board: GridPane) extends Thread{ var ss: ServerSocket = _ var sc: Socket = _ var br: BufferedReader = _ var pw: PrintWriter = _ var clientMsg: String = _ var arr: Array[String] = _ def createServer: Unit ={ try{ ss = new ServerSocket(port) println("Waiting For・・・") sc = ss.accept() println("Welcome!!") //以下、メッセージやり取りのための変数初期化 try { br = new BufferedReader(new InputStreamReader(sc.getInputStream)) pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sc.getOutputStream))) }catch { case e: Exception => e.printStackTrace } } catch { case e:Exception => e.printStackTrace ss.close() } } def createCircle(posX: Int, posY: Int, color: Color): Unit ={ println("Server:" + posX + "," + posY) board.add(new Circle(0,0,27,color), posX , posY) } def sendMsg(msg: String): Unit = { arr = msg.split(",") pw.println(msg) pw.flush() createCircle(arr(0).toInt, arr(1).toInt, Black) } def receiveMsg(): Unit ={ while((clientMsg = br.readLine()) == null){Thread.sleep(100)} println(clientMsg) arr = clientMsg.split(",") createCircle(arr(0).toInt, arr(1).toInt, White) } }
Client.scala
package network import java.io._ import java.net._ import java.util._ import javafx.scene.shape.Circle import scalafx.scene.paint.Color._ import scalafx.scene.layout.GridPane import scalafx.scene.paint.Color class Client(val sc: Socket, val board: GridPane){ var br: BufferedReader = _ var pw: PrintWriter = _ var serverMsg: String = _ var arr: Array[String] = _ def createClient(): Unit ={ try { br = new BufferedReader(new InputStreamReader(sc.getInputStream)) pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sc.getOutputStream))) }catch { case e: Exception => e.printStackTrace } } def createCircle(posX: Int, posY: Int, color: Color): Unit ={ println("Client:" + posX + "," + posY) board.add(new Circle(0,0,27,color), posX , posY) } def sendMsg(msg: String): Unit = { arr = msg.split(",") pw.println(msg) pw.flush() createCircle(arr(0).toInt, arr(1).toInt, White) } def receiveMsg(): Unit ={ while((serverMsg = br.readLine()) == null){Thread.sleep(100)} println(serverMsg) arr = serverMsg.split(",") createCircle(arr(0).toInt, arr(1).toInt, Black) } }
試したこと
createCircle関数の挿入位置を、変えたりしました。要は、reciveMsg関数内部の処理がブロッキングだと思うので、それ以降応答が止まるのはわかるのですが、その前に描画処理をしているにもかかわらず、(中のprintln関数は走ったので、正しく処理に入って入る)円の描画が行われません。
補足情報(FW/ツールのバージョンなど)
scala 2.12.7
scalar 8.0.144
jdk-9
回答1件
あなたの回答
tips
プレビュー