用Scala实现一台机器到另一台机器的分布式计算功能
配置文件
summer.properties
server.port = 9999
server.host = localhost
【读取配置文件工具类】
object PropertiesUtil{
// 绑定配置文件
// ResourceBundle用于读取配置文件,所以读取时,不需要增加扩展名
val summer: ResourceBundle = ResourceBundle.getBundle("summer")
def getValue(key:String): String ={
summer.getString(key)
}
}
【Application】
class Application{
var envData: Any = null
def start(s:String)(op: => Unit):Unit = {
// 1.初始化环境
if(s == "socket"){
envData = new Socket(PropertiesUtil.getValue("server.host"),
PropertiesUtil.getValue("server.port").toInt)
}else if (s == "serverSocket"){
envData = new ServerSocket(PropertiesUtil.getValue("server.port").toInt)
}
// 2.业务逻辑
try{
op
} catch{
case ex:Exception =>
println("有异常出现:"+ ex.getMessage)
}
//3.环境关闭
if(s == "socket"){
val socket:Socket = envData.asInstanceOf[Socket]
if(!socket.isClosed){
socket.close()
}
}else if(s == "serverSocket"){
val server : ServerSocket = envData.asInstanceOf[ServerSocket]
if(!server.isClosed){
server.close()
}
}
}
}
【Task类】
class Task extends Serializable{
var data : Int = 0
var logic : Int => Int = null
def compute(): Int = {
logic(data)
}
}
【客户端】
object Scala_Client extends Application{
def main(args:Array[String]):Unit = {
// 1.调用 Application中的 start,传入参数和编写逻辑代码(op)
start("socket"){
// 2.如果环境变量 是 Socket的话 获取这个对象
val client:Socket = envData.isInstanceOf[Socket]
// 3.通过这个客户端对象获取输出流,包装成为 对象
val outObject:ObjectOutputStream = new ObjectOutputStream(client.getOutputStream)
// Out 向服务器输出 --> 对象
val task: Task = new Task()
// 把数据和逻辑都传过去,在服务端再执行具体运算逻辑
task.data = 10
task.logic = (x:Int) => {x*2}
outObject.writeObject(task)
outObject.flush()
//关闭Client的 socket的输出流,但是输入流可用
client.shutdownOutput()
// Int 客户端获取服务器的返回结果,并包装成为对象
val inObject: ObjectInputStream = new ObjectInputStream(client.getInputStream)
val result:Int = inObject.readObject().isInstanceOf[Int]
println("获取计算结果:"+result)
client.shutdownInput()
}
}
}
【服务器】将客户端传过来的数据和逻辑代码 在这里进行计算,计算后将结果返回给客户端
object Scala_Server extends Application{
def main(args: Array[String]):Unit = {
start("serverSocket"){
// 1.判断传入的参数生成的 envData 是否是 ServerSocket
val server: ServerSocket = envData.asInstanceOf[ServerSocket]
// 2.不断的循环读取客户端的请求,处理请求
while(true){
var client: Socket = server.accept() // 服务器不断的可以接收请求
new Thread(
new Runnable {
override def run():Unit = {
//In 获取客户端的发来的数据流,包装成对象
val inObject: ObjectInputStream = new ObjectInputStream(client.getInputStream)
//读取这个对象判断是否是否 是 Task 是就转
val task:Task = inObject.readObject().asInstanceOf[Task]
// 关闭输入流
client.shutdownInput()
//3.Out
val outputObject:ObjectOutputStream = new ObjectOutputStream(client.getOutputSteam)
import com.test.summer.framework.bean.Task
val result:Int = task.compute() // 已经拿到了 logic,data,可以直接调用此方法
// 计算后写出 --> 返回给客户端
outputObject.writeObject(result)
client.shutdownOutput()
if(!client.isClosed){
client.close()
}
client = null
}
}
).start()
}
}
}
}