Article View: pl.comp.lang.java
Article #153866Re: "Usieciowienie" gier
From: Arivald
Date: Mon, 23 Sep 2013 05:00
Date: Mon, 23 Sep 2013 05:00
156 lines
7043 bytes
7043 bytes
W dniu 2013-09-11 11:08, TheGuru pisze:
> Witajcie,
>
> napisałem kilka gier logicznych (kolejne czekają )
> https://play.google.com/store/apps/developer?id=TheGuru#?t=W251bGwsbnVsbCxudWxsLDEsImNvbS50aGVndXJ1Lm1hdGhncmFwaCJd.
> Gry tracą na atrakcyjności kiedy można grać tylko na 1 urządzeniu (a
> niektóre nie mają sensu kiedy znasz "karty" przeciwnika).
>
> Od jakiegoś czasu próbuje dodać do nich obsługę sieci ale idzie mi
> gorzej niż po grudzie.
> Przerobiłem podobne wątki na tym forum ale nie ogarnąłem tematu.
>
> Może mam złe założenia i w ogóle nie idę w dobrym kierunku.
>
> Komunikację wyobrażam to sobie jak w np GG. Pierwszy zawodnik wykonuje
> ruch i w formie krótkiego stringa wysyłam informację np 10050906 co by
> znaczyło że z pola 10:5 wykonuje ruch na pole 9:6.
>
> W sieci znalazłem kod prostego komunikatora napisanego w C. Próbowałem
> go przerobić na interfejs androida ale cos mi nie poszło bo nie mam
> komunikacji.
>
> Aplikacje uruchamiam w 2 oknach AVD licząc, że będę mógł pisać z jednego
> do drugiego, jak to działało w przykładzie C.
> Niestety na andku nie działa. Jak by co to mam wykupiony serwer (co
> prawda do zdjęć, ale mam dostęp do ftp i chyba mogę go użyć jeśli będzie
> taka potrzeba).
>
> Będę zobowiązany jeśli ktoś poświęci swój czas by mi pomóc.
>
> Poniżej przesyłam kod.
> To NIE JEST użyteczna aplikacja tylko program testujący :-)
>
Trochę teorii:
Są dwie metody komunikacji.
1) klient - serwer - klient
Ta metoda jest najpopularniejsza. Wymaga działającego serwera w
internecie. Każdy klient komunikuje się tylko z serwerem, a serwer
rozsyła dane jednego klienta do innych.
Co do twojego "serwera do zdjęć i ftp", to może się nie nadawać. Tzn
żeby działał jako serwer aplikacji, musiał byś mieć dostęp do
programowania na nim. Np. możliwość umieszczania servletów Javy, albo
chociaż strony WWW z PHP. Oczywiście kod serwera jest zupełnie różny od
kodu klientów ;-)
2) peer - to - peer
Wtedy każda aplikacja Androidowa jest równocześnie serwerem i klientem.
Zaleta że nie wymaga serwera, wada że trudniej zestawić połączenie.
Użytkownicy raczej nie będą wpisywać numerów IP, tym bardziej że
aktualne IP może się zmieniać. Można to rozwiązać np. wysyłając
"broadcasty", ale to działa tylko w aktualnej domenie rozgłoszeniowej,
czyli w tym wypadku w aktualnej sieci WiFi.
Są też metody hybrydowe, np używa się serwera w internecie do
zestawiania połączeń, przebijania NATów, etc, a potem realna transmisja
jest już peer-to-peer.
Zobacz jeszcze komentarze w kodzie.
> @Override
> protected void onCreate(Bundle savedInstanceState) {
> super.onCreate(savedInstanceState);
> setContentView(R.layout.activity_main);
>
> tvWyswietl = (TextView) findViewById(R.id.tvTresc);
> etNapisz = (EditText) findViewById(R.id.etZdanie);
> bStworz = (Button) findViewById(R.id.bStworz);
> bPolacz = (Button) findViewById(R.id.bPolacz);
> bWyslij = (Button) findViewById(R.id.bWyslij);
>
> bStworz.setOnClickListener(this);
> bPolacz.setOnClickListener(this);
> bWyslij.setOnClickListener(this);
>
> serwer = new Serwer(tvWyswietl,etNapisz);
> klient = new Klient("127.0.0.1");
Na pewno "127.0.0.1"? ten adres zawsze oznacza połączenie do samego
siebie. Zauważ że każdy AVD czy działające urządzenie to osobny
komputer, i dla każdego z nich "127.0.0.1" oznacza "ja".
Żeby połączyć się z innym AVD musisz znać jego IP, tak jak ono wygląda z
aktualnego AVD. A najprawdopodobniej go nie ma, ponieważ każdy AVD jest
połączony z hostem poprzez NAT.
Tu masz rozwiązanie problemu:
http://stackoverflow.com/questions/4683854/connecting-2-emulator-instances-in-android/4738690#4738690
> @Override
> public void onClick(View v) {
>
> switch (v.getId()) {
> case R.id.bStworz:
> serwer.startRunning();
> //tvWyswietl.setText("start running");
> break;
> case R.id.bPolacz:
>
> break;
> case R.id.bWyslij:
>
> break;
> }
[...]
> // ustanowienie i uruchomienie serwera
> public void startRunning() {
> try {
> tvTresc.append("\npróba \n");
> server = new ServerSocket(6789, 100);
> tvTresc.append("Serwer : " + String.valueOf(server));
> while (true) {
> tvTresc.append("próba 2");
> try {
>
> waitForConnection();
> setupStreams();
> whileChatting();
> } catch (EOFException eofException) {
> showMessage("\n Server zakończył połączenie");
> } finally {
> closeCrap();
> tvTresc.setText("próba 3");
> }
> }
Tu uruchamiasz nieskończoną pętlę, a chwilę wcześniej wołasz
startRunning() z wątku GUI... To przepis na powieszenie aplikacji.
Zrestą whileChatting() też zawiera niekończoną pętlę, ergo blokujesz
pętlę w startRunning() dopóki klient się nie rozłączy...
Generalnie pętla serwera powinna działać w osobnym wątku. startRunning()
powinno tylko uruchamiać ten wątek, i od razu zwracać kontrolę. A sam
serwer powinien uruchamiać nowy wątek dla każdego podłączonego klienta.
Wtedy pętle na socketach nie będą blokować nic innego.
I oczywiście z wątków komunikacji sieciowej nie wolno Ci odwoływać się
bezpośrednio do GUI, musisz to robić poprzez odpowiedni mechanizm
przesyłana komunikatów ( klasa Handler() ).
Osobiście radził bym Ci zrobić do komunikacji sieciowej osobną usługę
(obiekt Service), żeby połączenia nie były zależne od aktualnego Activity.
Sporo nauki przed Tobą ;-)
--
Arivald
Technical Details
Message-ID:
<l1oi3o$uj6$1@news.dialog.net.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!news.supermedia.pl!newsfeed.pionier.net.pl!news.dialog.net.pl!not-for-mailReferences:
<l0pbtl$k7b$1@news.icpnet.pl>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!news.supermedia.pl!newsfeed.pionier.net.pl!news.dialog.net.pl!not-for-mail From: Arivald <NOSPAMarivald@interia.pl> Newsgroups: pl.comp.lang.java Subject: Re: "Usieciowienie" gier Date: Mon, 23 Sep 2013 07:00:47 +0200 Organization: Dialog Net Lines: 158 Message-ID: <l1oi3o$uj6$1@news.dialog.net.pl> References: <l0pbtl$k7b$1@news.icpnet.pl> NNTP-Posting-Host: dynamic-78-8-159-72.ssp.dialog.net.pl Mime-Version: 1.0 X-Trace: news.dialog.net.pl 1379912632 31334 78.8.159.72 (23 Sep 2013 05:03:52 GMT) X-Complaints-To: abuse@dialog.net.pl NNTP-Posting-Date: Mon, 23 Sep 2013 05:03:52 +0000 (UTC) User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.0 In-Reply-To: <l0pbtl$k7b$1@news.icpnet.pl> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit