2010-04-21 33 views
5

मैं जावा सीखने की कोशिश कर रहा हूं। मैं एक सरल नेटवर्क कनेक्ट कनेक्ट 4 गेम के साथ-साथ चैट फीचर को भी कार्यान्वित करना चाहता हूं।जावा सर्वर सॉकेट चैनल सॉकेट चैनल (कॉलबैक)

मैं अपने नेटवर्क तर्क को अवरुद्ध करना चाहता हूं ताकि बहुत से अध्ययन के बाद मुझे पता चला कि सॉकेट चैनल मेरी आवश्यकताओं को दोबारा करने के बाद है।

सॉकेट चैनल्स में कॉलबैक फ़ंक्शंस की कमी अभी भी समझ में नहीं आई है .. जैसा कि सी # में मिलता है।

इस समय के लिए मेरी क्वेरी है: मैं चैट या गेम फॉर्म (जेएफआरएएम) में प्राप्त डेटा कैसे वितरित करूं?

कुछ मार्गदर्शन का स्वागत है।

+0

मेरा सुझाव है कि आप गैर-अवरुद्ध I/O के बजाय एकाधिक धागे का उपयोग करें। –

उत्तर

13

आपको एक चयनकर्ता का उपयोग करने की आवश्यकता है। पहले की घटनाओं प्राप्त करने के लिए एक चयनकर्ता बनाएँ:

SelectionKey acceptKey = server.register(selector, SelectionKey.OP_ACCEPT); 

तो फिर तुम घटनाओं पर कार्रवाई करने के आते ही उन्हें (आप चयनकर्ता उपयोग करने की आवश्यकता:

Selector selector = Selector.open() 

तो फिर तुम चयनकर्ता के साथ ServerSocketChannel रजिस्टर करने की आवश्यकता प्रक्रिया के "कॉलबैक" भाग के रूप में इस के बारे में सोच सकते हैं:

while(true){ 
    //how many channel keys are available 
    int available = selector.select(); 
    //select is blocking, but should only return if available is >0, this is more of a sanity check 
    if(available == 0) continue; 

    Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); 
    while(keys.hasNext()){ 
    SelectionKey key = keys.next(); 
    keys.remove(); 
    //someone is trying to connect to the server socket 
    if(key.isAcceptable()) doAccept(key); 
    //someone is sending us data 
    else if(key.isReadable()) doRead(key); 
    //we are trying to (and can) send data 
    else if(key.isWritable()) doWrite(key); 
} 

मांस doAccept(), doRead(), और doWrite() में होगा एक कुंजी चयन कुंजी inf शामिल होंगे स्वीकार के लिए। नई सॉकेट बनाने के लिए संमिश्रण। ताकि चयनकर्ता से प्राप्त की घटनाओं एक कनेक्शन (उदाहरण के लिए यह अपने खेल में एक खिलाड़ी हो सकता है) के लिए जिम्मेदार ठहराया जा सकता

doAccept(SelectionKey key){ 

//create the new socket 
SocketChannel socket = ((ServerSocketChannel)key.channel()).accept(); 
//make it non-blocking as well 
socket.configureBlocking(false); 

... 
//here you would likely have some code to init your game objects/communication protocol, etc. and generate an identifier object (used below). 
//and be able to find the socket created above 
... 

//Since it is non blocking it needs a selector as well, and we register for both read and write events 
SelectionKey socketKey = socket.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE); 
// so we can identify the events as they come in 
socketKey.attach(someSocketIndentifier); 
} 

अंतिम पंक्ति कुंजी को किसी वस्तु कहते हैं। तो अब आप नए कनेक्शन स्वीकार कर सकते हैं और आपको बस पढ़ने और लिखने की आवश्यकता होगी।

doRead(SelectionKey key){ 
    //here we retrieve the key we attached earlier, so we now what to do/wheer the data is coming from 
    MyIdentifierType myIdentifier = (MyIdentifierType)key.attachment(); 
    //This is then used to get back to the SocketChannel and Read the Data 
    myIdentifier.readTheData(); 
} 
लिखने के लिए

इसी तरह

doWrite(SelectionKey key){ 
    //here we retrieve the key we attached earlier, so we now what to do/wheer the data is coming from 
    MyIdentifierType myIdentifier = (MyIdentifierType)key.attachment(); 
    //This is then used to get back to the SocketChannel and Read the Data 
    myIdentifier.getSocketHandler().writePendingData(); 
} 

पढ़ना काफी सीधे आगे तुम सिर्फ एक ByteBuffer बनाने और उसके बाद फोन SocketChannels पढ़ें (ByteBuffer) (या उसके संस्करण में से एक) के आंकड़ों पर तैयार होने के लिए है, चैनल खाली होने तक।

लेखन थोड़ा जटिल काम है के रूप में आप आमतौर पर बफ़र होना जब तक आप लिखने घटना प्राप्त डेटा लिखा जा करना चाहते हैं:

class MyNetworkClass{ 
    ByteBuffer writeBuffer = ByteBuffer.allocate(1024); 
    SocketChannel commchannel; //from the server accept processing 

    ... 

    public void write(byte[] data){ 
    //here the class writeBuffer object is filled with the data 
    //but it isn't actually sent over the socket 
    ... 
    } 

    public void writePendingData(){ 
    //here actually write the data to the socket 
    commchannel.write(writeBuffer); 
    } 
} 

ध्यान दें कि आप में कक्षा में बफर प्रबंधन करने के लिए उचित कोड की आवश्यकता होगी घटना पूरी हो जाती है, या लिखने के लंबित विधि में इसे उचित रूप से संशोधित करने के लिए यदि बफर में मौजूद सभी डेटा सॉकेट में नहीं लिखा जाता है, साथ ही विभिन्न अपवाद जिन्हें प्रक्रिया के दौरान फेंक दिया जा सकता है। उम्मीद है कि यह आपको शुरू करने में मदद करता है।

+0

यह बहुत उपयोगी रहा है, मैं अब प्रक्रिया को बेहतर समझता हूं। – iTEgg

संबंधित मुद्दे