Commit 307257db by 王宇航

1.6.0

1、初步寫好KDS主動獲取POS信息的功能
parent 57140fe4
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="" vcs="Git" />
</component> </component>
</project> </project>
\ No newline at end of file
...@@ -55,7 +55,7 @@ afterEvaluate { ...@@ -55,7 +55,7 @@ afterEvaluate {
groupId = "com.gingersoft.connect" groupId = "com.gingersoft.connect"
artifactId = "Connect" artifactId = "Connect"
version = "1.5.9" version = "1.6.0"
// 添加 POM 配置 // 添加 POM 配置
// pom { // pom {
// name.set("GingerSoftConnect") // name.set("GingerSoftConnect")
......
package com.gingersoft.connect.bean package com.gingersoft.connect.bean
enum class Action { enum class Action {
KitchenInfo, SoldOutInfo KitchenInfo, FoodInfo, SoldOutInfo
} }
\ No newline at end of file
package com.gingersoft.connect.bean
import com.gingersoft.connect.utils.MsgProcess
interface GetFoodInfoProcess : MsgProcess
\ No newline at end of file
package com.gingersoft.connect.bean
import com.gingersoft.connect.utils.MsgProcess
interface GetSoldOutInfoProcess : MsgProcess
...@@ -21,6 +21,8 @@ class MessageBuilder( ...@@ -21,6 +21,8 @@ class MessageBuilder(
} }
fun initSendData(action: Action, sendData: SendMsgType): MessageSender { fun initSendData(action: Action, sendData: SendMsgType): MessageSender {
// 發送的消息有 RicePOS沽清後通過打印列表主動連接並通知沽清
// PRJ數據
val currentMsgCode = msgCode.incrementAndGet() val currentMsgCode = msgCode.incrementAndGet()
val msg = MessageBean(currentMsgCode, action.toString(), GsonUtils.GsonString(sendData)) val msg = MessageBean(currentMsgCode, action.toString(), GsonUtils.GsonString(sendData))
return MessageSender(connect, webSocketClient, msg) return MessageSender(connect, webSocketClient, msg)
......
package com.gingersoft.connect.bean
class ResultBean(
val success: Boolean = true,
val errorMsg: String = "",
val data: SendMsgType
)
...@@ -4,5 +4,6 @@ class SocketCallbackBean( ...@@ -4,5 +4,6 @@ class SocketCallbackBean(
val success: Boolean, val success: Boolean,
val statusCode: Int, val statusCode: Int,
val msgCode: String, val msgCode: String,
val errorMsg: String val errorMsg: String,
val data: SendMsgType
) )
\ No newline at end of file
package com.gingersoft.connect.bean;
/**
* 沽清用的食品信息類
*/
public class SoldOutFoodInfoBean {
/**
* 食品id
*/
private String foodId;
/**
* 食品名稱
*/
private String foodName;
/**
* 食品數量
*/
private Integer quantity;
/**
* 食品金額
*/
private double price;
/**
* 食品類型
*/
private int type;
public static final int TYPE_MAIN_FOOD = 1;
public static final int TYPE_FOOD = 2;
public static final int TYPE_ITEM_SPEC = 3;
/**
* 如果為0,type為1 || 2,則是食品組
* 如果有值,type為1 || 2,則是食品
* 如果為0,type為3,則是細項組
* 如果有值,type為3,則是細項
*/
private String parentId;
public String getFoodId() {
return foodId;
}
public void setFoodId(String foodId) {
this.foodId = foodId;
}
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
}
package com.gingersoft.connect.utils
import com.gingersoft.connect.bean.MessageBean
import com.gingersoft.connect.bean.SocketCallbackBean
/**
* 消息中轉,由具體的類去處理具體的事
*/
object MsgParser {
val parserMap by lazy { mutableMapOf<String, MsgProcess>() }
fun process(msgBean: MessageBean<*>?): SocketCallbackBean? {
return if (msgBean != null) {
val result = parserMap[msgBean.action.toString()]?.sendMsg()
if (result != null) {
SocketCallbackBean(
result.success,
200,
msgBean.code.toString(),
result.errorMsg,
result.data
)
} else {
return null
}
} else {
null
}
}
}
\ No newline at end of file
package com.gingersoft.connect.utils
import com.gingersoft.connect.bean.ResultBean
interface MsgProcess {
/**
* 消息處理
*/
fun sendMsg(): ResultBean
}
\ No newline at end of file
package com.gingersoft.connect.utils
import android.util.Log
import com.gingersoft.connect.bean.MessageBean
import org.java_websocket.WebSocket
import org.java_websocket.handshake.ClientHandshake
import org.java_websocket.server.WebSocketServer
import java.net.InetSocketAddress
class MyWebSocketServer(address: InetSocketAddress) :
WebSocketServer(address) {
val TAG = "MyWebSocketServer"
private val connections: HashSet<WebSocket> by lazy { HashSet() }
override fun onOpen(conn: WebSocket, handshake: ClientHandshake?) {
connections.add(conn)
Log.e(TAG, "服務端被連接")
conn.send("已連接")
}
override fun onClose(conn: WebSocket?, code: Int, reason: String?, remote: Boolean) {
connections.remove(conn)
Log.e(TAG, "${conn?.remoteSocketAddress?.hostString}客戶端斷開連接")
}
override fun onMessage(conn: WebSocket?, message: String?) {
Log.e(TAG, "收到消息:$message")
// 有KDS主動獲取食品、沽清信息接口
// RicePOS收到KDS要獲取食品的消息後,發送本地食品信息過去
message?.let {
val msg = GsonUtils.GsonToBean(message, MessageBean::class.java)
MsgParser.process(msg)?.let {
// 接受到消息並處理後,將結果返回回去
conn?.send(GsonUtils.GsonString(it))
}
}
}
override fun onError(conn: WebSocket?, ex: Exception?) {
Log.e(TAG, "服務器出錯: ${ex?.message}")
}
override fun onStart() {
Log.e(TAG, "開啟")
}
fun callbackMsg(msg: String) {
}
fun sendMessage(msg: String) {
connections.forEach {
it.send(msg)
}
}
}
\ No newline at end of file
package com.gingersoft.connect.utils
import android.content.Context
import android.net.nsd.NsdManager
import android.net.nsd.NsdManager.RegistrationListener
import android.net.nsd.NsdServiceInfo
import android.util.Log
class NSDUtils {
companion object {
private val TAG = "NSDUtils"
private val serviceName = "Gingersoft_NSD_KDS"
private val serviceType = "_http._tcp."
}
var registrationListener: NSDRegistrationListener? = null
fun registerKDS(context: Context) {
val nsdManager = context.getSystemService(Context.NSD_SERVICE) as NsdManager
val serviceInfo = NsdServiceInfo()
serviceInfo.serviceName = serviceName
serviceInfo.serviceType = serviceType
serviceInfo.port = 12583
registrationListener = NSDRegistrationListener()
nsdManager.registerService(
serviceInfo,
NsdManager.PROTOCOL_DNS_SD,
registrationListener
)
}
class NSDRegistrationListener : RegistrationListener {
var isRegistered = false // 已註冊
override fun onRegistrationFailed(nsdServiceInfo: NsdServiceInfo, i: Int) {
// 註冊失敗處理
Log.e(TAG, "註冊失敗 ${nsdServiceInfo.host}--$i")
isRegistered = false
}
override fun onUnregistrationFailed(nsdServiceInfo: NsdServiceInfo, i: Int) {
// 註銷失敗處理
Log.e(TAG, "註銷失敗 ${nsdServiceInfo.host}--$i")
isRegistered = false
}
override fun onServiceRegistered(nsdServiceInfo: NsdServiceInfo) {
// 注册成功
Log.e(TAG, "注册成功 ${nsdServiceInfo.host}--${nsdServiceInfo.serviceName}")
isRegistered = true
}
override fun onServiceUnregistered(nsdServiceInfo: NsdServiceInfo) {
// 註銷成功處理
Log.e(TAG, "註銷成功 ${nsdServiceInfo.host}")
isRegistered = false
}
}
fun unregisterService(context: Context) {
if (registrationListener != null && registrationListener!!.isRegistered) {
try {
val nsdManager = context.getSystemService(Context.NSD_SERVICE) as NsdManager
nsdManager.unregisterService(registrationListener)
} catch (e: IllegalArgumentException) {
} finally {
registrationListener = null
}
}
}
}
\ No newline at end of file
package com.gingersoft.connect.utils
import android.content.Context
import com.gingersoft.connect.bean.Action
import com.gingersoft.connect.bean.GetFoodInfoProcess
import com.gingersoft.connect.bean.GetSoldOutInfoProcess
import java.net.InetSocketAddress
object SoldOut {
/**
* 接收數據的服務
*/
private var mWebSocketServer: MyWebSocketServer? = null
private var nsdUtils: NSDUtils? = null
fun init(context: Context) {
// 註冊NSD,讓後面開啟的KDS能主動找到POS設備,然後從POS設備拿食品信息
nsdUtils = NSDUtils()
nsdUtils?.registerKDS(context)
// 開啟服務,接收KDS發來的消息
mWebSocketServer = MyWebSocketServer(InetSocketAddress(12581))
mWebSocketServer?.isReuseAddr = true // 設置地址可複用,避免APP被用戶強制殺掉後,再次打開報錯Address already in use
mWebSocketServer?.start()
}
fun initFoodInfoTransmitter(process: GetFoodInfoProcess) {
MsgParser.parserMap[Action.FoodInfo.toString()] = process
}
fun initSoldOutInfoTransmitter(process: GetSoldOutInfoProcess) {
MsgParser.parserMap[Action.SoldOutInfo.toString()] = process
}
fun stopServer() {
mWebSocketServer?.stop()
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment